给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明:
必须在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数。
链接:https://leetcode-cn.com/problems/move-zeroes
(1)直接做for循环?
(2)试试列表生成式?
(3)map函数?filter函数?
思路1
class Solution:
def moveZeroes(self, nums):
"""
Do not return anything, modify nums in-place instead.
"""
for i in nums:
if i == 0:
nums.remove(0)
nums.append(0)
?
分析:执行通过,用了for循环事件复杂度是O(n),其中for循环里嵌套了remove操作,移除了其中一个元素,其他元素都要向前面移动,保证排序的正确性,这个时间复杂度是O(n),append时间复杂度是O(1),所以整体的时间复杂O(n^2),需要优化。
思路2
def movezero2(nums):
nums = [ i if i != 0 else ‘‘ for i in nums]
return nums
?
print(movezero2(li1))
#不对,写不出来,可以去掉加不了0
?
思路3
def movezero3(nums):
nums = list(filter(lambda x:x!=0,nums))
return nums
#与思路2一样,可以去掉0,加不了0
去中文leetcode网站和英文站看题解,看官方题解,用点赞数排序,从点赞最多的看起。
优先看英文站,优秀解答比较多。
注意一点:有时候leetcode的官方题解还不如网友的题解。
解法1
class Solution:
def moveZeroes(self, nums):
"""
Do not return anything, modify nums in-place instead.
"""
i = j = 0
for i in range(len(nums)):
if nums[i] != 0:
nums[j] , nums[i]= nums[i] , nums[j]
j += 1
分析:第一次遇到非零元素,将非零元素与数组nums[0]互换,第二次遇到非零元素,将非零元素与nums[1]互换,第三次遇到非零元素,将非零元素与nums[2],以此类推,直到遍历完数组
这里遇到非零元素就互换,时间复杂度为O(n).
解法二
class Solution:
def moveZeroes(self, nums):
"""
Do not return anything, modify nums in-place instead.
"""
i = 0
end = len(nums)
while i < end:
if nums[i] == 0:
del nums[i]
nums.append(0)
end -= 1
else:
i += 1
?
分析:del num[i] 时间复杂度为O(n),但是用了i,i不断加一,所有这个时间复杂度近似于Olog(n),如果0元素越多则需要操作的就越少。执行时间也较解法一少。
解法三:
class Solution:
def moveZeroes(self, nums):
"""
Do not return anything, modify nums in-place instead.
"""
zeros_count = nums.count(0)
nums[:] = [ i for i in nums if i != 0]
nums += [0] * zeros_count
分析:
执行时间与解法一差不多,推荐解法二。
其中本地执行为
def moveZeroes(nums):
zeros_count = nums.count(0)
nums = [ i for i in nums if i != 0] #这一句与上面不一样
nums += [0] * zeros_count
return nums
返回值是正确的,但在leetcode-cn提交执行不正确,#TODO待研究。
leetcode的奇妙冒险(python3)系列:leetcode 283. Move Zeroes
原文:https://www.cnblogs.com/Nicholas0707/p/12741508.html