LeetCode4 - 移动零
📝 题目描述
题目链接:移动零
给定一个数组nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。
请注意,必须在不复制数组的情况下原地对数组进行操作。
示例:
1 |
|
提示:
1 <= nums.length <= 10^4-2^31 <= nums[i] <= 2^31 - 1
💡 解题思路
方法一:暴力解法
遍历数组(ptr1),每当遇到一个0时,就停下来。然后启动一个内层循环(ptr2),从当前位置向后扫描,寻找第一个非零元素。找到后,将两者交换,保证非零元素被挪到前面,0被挪到后面。
缺点: 被动地“填坑”,发现一个0,赶紧去找个数来填上。
方法二:快慢指针解法
使用两个指针,
left(慢指针): 维护非零数组的边界,含义是“下一个非零元素应该放置的位置”。
right(快指针): 负责在前探路,遍历整个数组。
当right遇到非零数,就把它和left位置的数交换,然后left向前推进一步。如果right遇到0,则忽略,继续前行。
刚开始时,left=right,都是0。
如果数组是[0,1],那么left刚开始指向0,right跳过0指向1,第一次交换后变为[1,0];
如果数组是[1,0],那么left刚开始指向1,right指向1,自我交换后还是[1,0],此时left会+1,指向0,right也会指向0并继续工作。
优点: 主动地“收集”,不管0在哪,我只把非零的数按顺序往前排,0自然就被挤到后面去了。
🔧 代码实现
1、暴力解法
1 | class Solution { |
2、快慢指针解法
1 | class Solution { |
📊 复杂度分析
1、暴力解法
- 时间复杂度:,假设数组是 [0, 0, 0, …, 0, 1],对于前面的每一个 0,内层循环都要遍历整个数组去寻找那个1。
- 空间复杂度:,在位交换,无额外开销。
2、快慢指针解法
- 时间复杂度:,right 指针只从头到尾遍历了一次数组。每个元素最多被访问和处理一次。
- 空间复杂度:,在位交换,无额外开销。
🎯 总结
- 核心思想:跳出双重循环思想,使用分离的思想,两个指针各司其职
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 很多时候不懂事!