Leetcode-探索 | 移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入:[0,1,0,3,12]
输出:[1,3,12,0,0]
说明:
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
————————————————————————————————————————————
解题过程:
数组问题没有特别好的思路的时候不妨试试用暴力的方法解决问题:遍历数组找到零元素并将其移动到数组尾端,保证元素有序的方法是选择移动零元素的方法为将其与其后相邻元素挨个交换直至尾端。
这里有一点优化的空间:如果简单直接地顺序遍历数组寻找零元素,每个零元素与其后相邻元素交换直至末尾,则算法的执行过程接近最差复杂度。因为不能识别数组末尾的“零段”,每个新探测到的零元素都必须被安置到数组尾端才能保证没有非零数字被遗忘。优化的办法是逆序遍历数组,每遇到一个零元素则将其顺序与相邻元素交换直至被置于数组尾端或遇到另一个零元素。这个优化方法可以保证新检索到的零元素总是待处理数组中的最后一个零元素,一旦遇到下标在其后的另一个零元素即可判断到达数组末尾的“零段”,节省了将此零元素继续与其他零元素交换的过程。另外,优化方法还能避免前述顺序暴力方法中较前的零元素跨越较后的零元素产生的交换。设数组中零元素的个数为k,则优化方法可以节约大概k2次交换。
附AC代码:
1 class Solution(object): 2 def moveZeroes(self, nums): 3 """ 4 :type nums: List[int] 5 :rtype: void Do not return anything, modify nums in-place instead. 6 """ 7 arrLen = len(nums) 8 for i in range(arrLen-1, -1, -1): 9 if nums[i] == 0: 10 for j in range(i, arrLen-1): 11 if nums[j+1] != 0: 12 nums[j] = nums[j+1] 13 nums[j+1] = 0
————————————————————————————————————————————
复杂度分析:
时间:考虑到零元素在数组中的位置,需要用概率平摊的分析方法,还没复习,暂不做分析;
空间:未使用附加空间。
————————————————————————————————————————————
题型总结:
一个数组问题,考察数组操作中的逆序技巧,对算法过程的掌控能力,优化算法的能力,发现和解决问题的能力;
可以把本题作为处理数组问题的典型技巧记忆,温习。