題目
給定一個非空列表 nums,請將 nums 中所有 0 移動到列表的末尾,同時保持非零元素的相對順序。
注意:只允許在原列表nums上操作,而不能返回一個新創建的列表。
例如:
給定一個列表:[0, 1, 0, 3, 12],返回結果:[1, 3, 12, 0, 0]
實現思路1
- 使用類似冒泡排序的方式(每次把較大的值交換移到後面),而這裏是每次把 0 移動到最後,但整個過程需要 2 層遍歷
- 第一層遍歷控制需要幾輪,同時設置一個交換標記flag,默認爲True
- 第二層遍歷控制每次比較元素下標,如果發現當前元素爲 0 ,且下一個元素不爲 0 ,那麼就把二者順序交換,並把flag置爲False
- 每輪循環都能夠把一個 0 移動到列表末尾,直到發現某次循環中,列表已經是排序好的,沒有進行任何元素交換(flag=True),那麼就可以直接break退出,並返回列表
代碼實現
def moveZeroes(nums):
for i in range(len(nums)):
flag = True
for j in range(len(nums) - i - 1):
if nums[j] == 0 and nums[j + 1] != 0:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
flag = False
if flag:
break
return nums
實現思路2
- 設置一個index,表示列表的下標,默認值爲 0
- 遍歷nums,如果當前元素不爲 0 ,那麼就把列表nums中 index 下標對應的元素設置爲當前元素,同時令 index + 1,這樣遍歷完成後,前 index 個元素必然就是原列表 nums 中的所有非零元素
- 再次遍歷,起始位置爲 index ,結束位置爲 len(nums) ,每次都把列表 nums 中當前位置的元素設置爲 0 ,最後得到的 nums 即爲移動零後的結果
代碼實現
def moveZeroes(nums):
index = 0
for num in nums:
if num != 0:
nums[index] = num
index += 1
for i in range(index, len(nums)):
nums[i] = 0
return nums
實現思路3
- 設置2個變量 left 和 right ,left表示指向列表中非零元素的下標,right表示指向列表的下標
- 通過 while循環 來實現,只要滿足 right < len(nums) 都會進行循環
- 如果當前元素 nums[right] 爲 0 ,則 left 保持不變
- 如果當前元素 nums[right] 不爲 0,且同時滿足 left != right,那麼就需要交換 left 和 right 對應的元素,即把當前的非 0 元素移到前面去。但不管是否交換元素,最後 left 都需要向右移動,即 left + 1
- 不管當前元素 nums[right] 是否爲0,每次遍歷最後 right 都需要向右移動 ,即right + 1
使用上面方法,可以發現有以下特點:
- left左側的所有元素,都將是非 0 元素
- 從left右側到right左側的所有元素,都將是 0 元素
每次交換都是 left 當前對應的 0 元素與 right 對應的非 0 元素進行交換,所以最終得到的 nums 中,非零元素的相對順序是保持不變的。
代碼實現
def moveZeroes(nums):
left = right = 0
while right < len(nums):
if nums[right] != 0:
if left != right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right += 1
return nums