移动零
283. 移动零
题目描述: 2020/11/18
给定一个数组
nums
,编写一个函数将所有0
移动到数组的末尾,同时保持非零元素的相对顺序。说明:
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
if not nums:
return 0
count = 0
for i in range(len(nums)):
if nums[i] == 0:
count += 1
continue
temp = nums[i - count]
nums[i - count] = nums[i]
nums[i] = temp
自己的想法:2020/11/18
快速排序
- 找到0,不做改变,把当前不为0的数和第一个出现0的位置进行交换位置,这样虽然0的位置变了,但是不为0的数字按照正常顺序排列
为什么error:
- 使用了双重for循环,只能和当前位置进行交换,当变换完之后还是和当前位置进行交换,所以使得出现了很多0
解题思路:
一次遍历
这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点x,然后把所有小于等于x的元素放到x的左边,大于x的元素放到其右边。
这里我们可以用0当做这个中间点,把不等于0(注意题目没说不能有负数)的放到中间点的左边,等于0的放到其右边。
这的中间点就是0本身,所以实现起来比快速排序简单很多,我们使用两个指针i和j,只要nums[i]!=0,我们就交换nums[i]和nums[j]
请对照动态图来理解:时间复杂度: O(n)
空间复杂度: O(1)两次遍历 : 双指针
我们创建两个指针i和j,第一次遍历的时候指针j用来记录当前有多少非0元素。即遍历的时候每遇到一个非0元素就将其往数组左边挪,第一次遍历完后,j指针的下标就指向了最后一个非0元素下标。
第二次遍历的时候,起始位置就从j开始到结束,将剩下的这段区域内的元素全部置为0。
动画演示:时间复杂度: O(n)
空间复杂度: O(1)作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/move-zeroes/solution/dong-hua-yan-shi-283yi-dong-ling-by-wang_ni_ma/
感想:
时间过长,优化
class Solution: def moveZeroes(self, nums: List[int]) -> None: """ Do not return anything, modify nums in-place instead. """ count = 0 for i in range(len(nums)): if nums[i] == 0: count += 1 # 记录0有几个 continue if (i > i - count): # 如果i之前没有0,就不交换 nums[i - count] = nums[i] nums[i] = 0