leetcode的奇妙冒险(python3)系列:leetcode 283. Move Zeroes
题目:
给定一个数组 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函数?
写代码(first pass)
思路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网站和英文站看题解,看官方题解,用点赞数排序,从点赞最多的看起。
优先看英文站,优秀解答比较多。
注意一点:有时候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待研究。
posted on 2020-04-20 23:31 Nicholas-- 阅读(231) 评论(0) 编辑 收藏 举报