1. 程式人生 > 其它 >【陣列】力扣283:移動零

【陣列】力扣283:移動零

給定一個數組 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