【陣列】力扣283:移動零
阿新 • • 發佈:2022-03-30
給定一個數組 nums,編寫一個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。
請注意 ,必須在不復制陣列的情況下原地對陣列進行操作。
示例1:
輸入: nums = [0,1,0,3,12]
輸出: [1,3,12,0,0]
示例2:
輸入: nums = [0]
輸出: [0]
法一:兩次遍歷
建立兩個指標i和j,第一次遍歷的時候指標j用來記錄當前有多少非0元素。即遍歷的時候每遇到一個非0元素就將其往陣列左邊挪,第一次遍歷完後,j指標的下標就指向了最後一個非0元素下標。
第二次遍歷的時候,起始位置就從j開始到結束,將剩下的這段區域內的元素全部置為0。
class Solution(object): def moveZeroes(self, nums): """ :type nums: List[int] :rtype: None Do not return anything, modify nums in-place instead. """ if not nums: return 0 # 第一次遍歷的時候,j指標記錄非0的個數,只要是非0的統統都賦給nums[j] j = 0 for i in xrange(len(nums)): if nums[i]: nums[j] = nums[i] j += 1 # 非0元素統計完了,剩下的都是0了 # 所以第二次遍歷把末尾的元素都賦為0即可 for i in xrange(j,len(nums)): nums[i] = 0 作者:wang_ni_ma 連結:https://leetcode-cn.com/problems/move-zeroes/solution/dong-hua-yan-shi-283yi-dong-ling-by-wang_ni_ma/
時間複雜度: O(n)
空間複雜度: O(1)
法二:一次遍歷的氣泡排序
這裡參考了快速排序的思想,快速排序首先要確定一個待分割的元素做中間點x,然後把所有小於等於x的元素放到x的左邊,大於x的元素放到其右邊。
這裡我們可以用0當做這個中間點,把不等於0(注意題目沒說不能有負數)的放到中間點的左邊,等於0的放到其右邊。
這的中間點就是0本身,所以實現起來比快速排序簡單很多,我們使用兩個指標i和j,只要nums[i]!=0,就交換nums[i]和nums[j]
class Solution(object): def moveZeroes(self, nums): """ :type nums: List[int] :rtype: None Do not return anything, modify nums in-place instead. """ if not nums: return 0 # 兩個指標i和j j = 0 for i in xrange(len(nums)): # 當前元素!=0,就把其交換到左邊,等於0的交換到右邊 if nums[i]: nums[j],nums[i] = nums[i],nums[j] j += 1 作者:wang_ni_ma 連結:https://leetcode-cn.com/problems/move-zeroes/solution/dong-hua-yan-shi-283yi-dong-ling-by-wang_ni_ma/
時間複雜度: O(n)
空間複雜度: O(1)
法三:本人的一次遍歷暴力解法
class Solution: def moveZeroes(self, nums: List[int]) -> None: """ Do not return anything, modify nums in-place instead. """ z = 0 n = len(nums) for i in range(n): if nums[i] == 0: z += 1 else: if z > 0: # 可以直接寫為 nums[i - z], nums[i] = nums[i], 0 nums[i - z] = nums[i] nums[i] = 0