題目出處
難度
Easy
題目分類
array, two-pointers
個人範例程式碼 - 2022/5/11
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
m, n = m-1, n-1 # get last idx
for idx in range(len(nums1)-1, -1, -1):
if(m >= 0 and n >= 0):
if nums1[m] < nums2[n]:
nums1[idx] = nums2[n]
n -= 1
else:
nums1[idx] = nums1[m]
m -= 1
elif m >= 0:
nums1[idx] = nums1[m]
m -= 1
elif n >= 0:
nums1[idx] = nums2[n]
n -= 1
最近在練習程式碼本身就可以自解釋的 Coding style,可以嘗試直接閱讀程式碼理解
算法說明
從尾巴開始往前填,注意一下順序即可
input handling
在 for 迴圈中一起處理
Boundary conditions
for 迴圈控制範圍
個人範例程式碼 - 2022/2/25
class Solution(object):
def merge(self, nums1, m, nums2, n):
"""
:type nums1: List[int]
:type m: int
:type nums2: List[int]
:type n: int
:rtype: None Do not return anything, modify nums1 in-place instead.
"""
while (m > 0 and n > 0):
if(nums1[m-1] >= nums2[n-1]):
nums1[m+n-1] = nums1[m-1] # put nums1[m] in to the last place of nums1
m -= 1
else:
nums1[m+n-1] = nums2[n-1]
n -= 1
else:
while n > 0: # m = 0
nums1[m+n-1] = nums2[n-1]
n -= 1
# else m > 0, already in nums1
說明
這題我們可以先注意題目的敘述:
最需要思考的部分在於「題目希望最後的結果直接儲存在 nums1 裡面」
雖然這樣的限制會使我們解題更加的「受到限制」,但反過來說,
其實這也是題目給我們「最大的提示」。
題目的 nums1 給的空間為 m+n,所以最後我們都會將所有的值擺入 nums1 中,
而因為我們可以無憂慮去更改的值為最後的 0,0,0… 部分
(因為這個值就算被改消失了,也不影響我們想計算的結果)
所以這邊可以推斷出一定要「從後面開始解」,「從最無痛的 0 開始取代」,
再來我們就可以來思考,什麼時候擺入 nums1的值? 什麼時候擺入 nums2 的值?
我們可以靠著題目所給的 m, n 來進行這樣的操作,透過值不斷擺入,
我們去移動 m, n 作為 index 的座標,即可順利完成此題目。
邊際情況處理
這題要注意的邊際情況為 m=0, n=0 的時候我們要怎麼處理,
而照題目的敘述,
- n=0 基本上對我們來說沒差,因為 m 控制的 nums1 即代表我們要的答案
注意 index 細節,才是這題要考細心的部分
這題有很多 index 細節考驗著作答者的細心度,
包含:
- 迴圈的範圍僅限於 m, n > 0 時,其他需要進例外處理
- m-1, n-1 才是當下座標
- 要擺入的位置為 m+n-1
- 處理到 n > 0 就應該停下,而非 n >= 0
python while-else 用法說明
一般來說,我們通常都只會使用到 while,
但其實在 python 中,while 是可以搭配 else 使用的。
邏輯如下:
while(條件成立):
# 成立時循環
else: # 當不成立時,出現在這
# 當條件不成立時,開始作這邊的事情
這個寫法,可能很多人覺得好像有沒有 else 似乎不會有太大的影響?
畢竟當 while 條件不成立後,後續的程式碼「本來就會執行」
沒有錯!!!! 但是這個小細節,卻可以讓我們的程式碼邏輯更漂亮!
例如說當我們有無關 while 的相關內容,我們才應該擺在外面,
但有時候是剛結束迴圈時有一些收尾的相關內容要處理,這時候用 else 的寫法就相當漂亮了!
範例
假設我們要把一個 mylist 「純手動」印成 [1,2,3] 的樣子,
最後還要印出一個 finish!
mylist = [1,2,3]
idx = 0
print('[', end = '')
while(idx < len(mylist)):
print(mylist[idx], ',')
idx += 1
else:
print(']')
print('finish!')
這個例子應該就很好懂了,我們集中「把要處理 list 列印的動作」放在 while-else 裡面,
最後比較無關的 finish! 放在 while-else 外面,
這樣看起來程式碼邏輯有沒有比都放在外面更清楚了呢? (當然,見仁見智啦XDDD,我覺得有XD)
特殊用法 - while-else 搭配 break 使用的情況
這也是我近期解題才發現的,當 while - else 搭配 break 使用時,能發揮更好閱讀的效果!
請讀者先想像一下,下面的程式碼會印出什麼呢?
while(True):
break
else:
print(1)
print(2)
答案不是 1 2 !!! 而是只有 2 !!!
這樣我們就能夠更進階的使用這個功能了,
- 「透過 while 迴圈條件結束的,寫在 else 裡面」
- 「如果是透過 break 結束的,寫在最外面」
使用方式可以看我下面這題的示範:
https://wongwongnotes-github-io.pages.dev/python/leetcode-python-142/