283. Move Zeroes(移动零)
题目链接: 283. Move Zeroes
Difficulty: Easy
Topics: Arrary, Two Pointers
Question
Given an integer array , move all 's to the end of it while maintaining the relative order of the non-zero elements.
Note that you must do this in-place without making a copy of the array.
Example 1:
Input: nums = [0, 1, 0, 3, 12]
Output: [1, 3, 12, 0, 0]
Example 2:
Input: nums = [0]
Output: [0]
Constraints:
Follow up:
- Could you minimize the total number of operations done?
解题思路
方法1:
思路
我们需要把所有的数组中原有的所有0都挪到这个数组的最末尾去,而且要求不创建新的数组原地修改。那么最直接的想法就是遍历一遍,出现0就在末尾添加一个,然后把原有位置的删掉。
代码
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
zero_count = 0 # 记录0的个数
for i in range(len(nums)):
if nums[i - zero_count] == 0:
nums.append(0) # 末尾添加0
del nums[i - zero_count] # 删掉中间出现的0
zero_count += 1
复杂度
- 时间:我们进行了一次从头到位的遍历,时间为。但在这其中我们使用了,消耗时间也是(因为数组本身的性质导致删除一位数的这种操作,实际上就是把后面所有的数都每一个往前挪动了一位。总计就是,可以说非常糟糕了。
- 空间:在原有位置操作,只记录了zero_count,空间消耗为。
方法2:
思路
根据题目的标签提示,有双指针这个关键词,那我们也来个双指针。我们这个时候的双指针使用一慢一快同时从头开始,慢的记录非0的元素需要填充的位置(出现一波0的第一个0的位置),或者说就是我们之前算法的i - zero_count。快就是我们之前的i。
代码
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
slow = 0
for fast in range(len(nums)):
if nums[fast] != 0:
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
复杂度
- 时间:我们只进行了一次从头到位的遍历,总时间复杂度为。
- 空间:在原有位置操作,只记录了slow指针,空间消耗为。