08 移动零-20200320
题目
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
注意事项:
- 不能额外开辟新空间。
- 注意空数组。
思路一
直接一次遍历,找到0进行pop()操作,再将0进行insert()插到最后。
修改经历:
1. 没有考虑到两个零相邻的情况,这样的话,循环会一直卡在这里。(第一次提交)
- 解答错误
2. 换了个思路,将pop和insert分开做,先弹出再再最后insert0。但是这个内存很是很大,每次都是14MB左右。(第二次提交)
- 执行用时 :36 ms, 在所有 Python3 提交中击败了95.86%的用户
- 内存消耗 :14 MB, 在所有 Python3 提交中击败了5.02%的用户
心得体会:
要注意while和for的区别,for里的索引会一直增加,如果想要自己控制指针的话,还是用while好。
最终代码展示:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
if len(nums) != 0:
length, i = len(nums), 0
while i < len(nums):
if nums[i] == 0:
nums.pop(i)
else:
i += 1
nums.append(0)
else:
pass
for _ in range(0, length-len(nums)):
nums.append(0)
return nums
思路二
采用双指针,一个向前遇到0弹出,指针不变,遇到非零加一。一个向后,当弹出0时插入,并减一。最后两个相等结束。
修改经历:
1. 一次就成了。(第一次提交)
- 执行用时 :36 ms, 在所有 Python3 提交中击败了95.86%的用户
- 内存消耗 :14.1 MB, 在所有 Python3 提交中击败了5.02%的用户
心得体会:
当问题分析清楚了,还是很容易就解决了。
最终代码展示:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
if len(nums) != 0:
i, j = 0, len(nums)
while i < j:
if nums[i] == 0:
nums.insert(j, 0)
nums.pop(i)
j -= 1
else:
i += 1
else:
pass
return nums
思路三
这个思路是从题解大神那学来的,就是交换项。两个指针 i 和 j,i 只管向前走,遇到非零元素就和 j 交互,遇到0就pass。j 遇到非零元素元素,交换后加一。这样,j 就会小于等于 i。开始时 i 和 j 一起走,当 i 遇到 0时跳过,此时 j 就留在了0上。所以交换时就会把0换到后面。
修改经历:
1. 大神就是大神,服了。(第一次提交)
- 执行用时 :28 ms, 在所有 Python3 提交中击败了99.59%的用户
- 内存消耗 :14.1 MB, 在所有 Python3 提交中击败了5.02%的用户
心得体会:
这个换位的想法很妙啊,真的很妙,强烈推荐的!!有大神说这是 Cyclic Sort(循环排序)
最终代码展示:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
if len(nums) != 0:
j = 0
for i in range(0, len(nums)):
if nums[i] != 0:
nums[i], nums[j] = nums[j], nums[i]
j += 1
return nums