一.问题描述
Given an array nums
, write a function to move all 0
's to the end of it while maintaining the relative order of the non-zero elements.
Example:
Input:[0,1,0,3,12]
Output:[1,3,12,0,0]
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations.
二.解题思路
这道题要求in-place 改变,不能有返回值,也就是最好不要新开变量来弄。
方法主要有2种:
1.新开变量,最后把新开变量的值赋给原变量,这种很简单,不过貌似不是题目想要我们做的意思。
不过这种时间复杂度最低,是O(N)
2.考虑in-place就要考虑如何删元素,可以用del,也可以用切片来覆盖
时间复杂度O(N*N)
更新两个方法:
1.用count计数0的次数,最后用remove删除并用append加相应的0到末尾
2.用双指针,一个指针记录上一个0的位置,一个指针记录自上一个零之后第一个非零出现的位置,然后交换这两个元素值。
更新两指针。
更多leetcode算法题解法: 专栏 leetcode算法从零到结束
三.源码
第一种方法我就不写了,比较简单,用个指针记录一下零排在尾的个数就好了。
class Solution:
# del
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
len_nums,i=len(nums),0
while i<len_nums:
if nums[i]==0:
del nums[i]
i-=1
len_nums-=1
nums.append(0)
i+=1
# if use for-loop, use offset
# for i in range(len(nums): nums[i-offset]==0
# slice
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
len_nums,i,cnt=len(nums),0,len(nums)
while i<cnt:
if nums[i]==0:
nums[i:len_nums-1]=nums[i+1:len_nums]
nums[len_nums-1]=0
i-=1
cnt-=1
i+=1
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# 直觉做法
# for num in nums:
# if num ==0:
# nums.remove(num)
# nums.append(num)
# 双指针
indx =0
for i in range(len(nums)):
if nums[i] != 0: #如果当前不为0 互换两指针数值,为零则数组指针继续前进
nums[indx],nums[i]=nums[i],nums[indx]
indx +=1
# print(nums)
return nums
# 先数有几个0,把所有0移除最后在append回去
# count = nums.count(0)
# for i in range(count):
# nums.remove(0)
# nums.append(0)
# return nums