[LeetCode移动零] | 刷题打卡
第12题了,本想发个大招,但时间有限,题库里没刷过特别难的双指针问题,来一道移动0的问题放松下!
一直有刷题习惯,最近才看到掘金举办了刷题活动,特来参加!此题为第12题。不得不说掘金的主题就是漂亮呀!赞。
本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
例1:
输入: nums = [0, 1, 0, 3, 12],
输出: [1, 3, 12, 0, 0].
例2:
输入: nums = [0, 0, 0, 3, 1],
输出: [3, 1, 0, 0, 0].
例3:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
二、思路分析:
方法 | 描述 | 时间复杂度 | 空间复杂度 |
---|---|---|---|
双指针 | 同向双指针,两种做法 | ||
第一步 | left 记录新数组,right 记录旧数组, | ||
第二步 | 遍历旧数组,移动right 指针,旧数组不为0 ,left 和right 同时移动 | ||
第三步 | 旧数组为0 ,仅right 移动,left 记录为0 的位置 | ||
第四步 | 旧数组不为0 时,有两种做法:方法1:将 right 和left 的值互换,left 和right 同时移动 | ||
第五步 | 方法2:将right 的值赋值给left 位置,在遍历结束之后,将[0,1,2...left,..right] 中left->right 之间非0 的值重写为0 |
三、AC 代码:
两种思路 way1在注释中 way2已经打开
// @lc code=start
class Solution {
public void moveZeroes(int[] nums) {
int left = 0;
int right = 0;
// ways 1:
// while (right < nums.length) {
// if (nums[right] != 0) {
// int temp = nums[left];
// nums[left] = nums[right];
// nums[right] = temp;
// left++;
// }
// right ++;
// }
// way 2
while (right < nums.length) {
if (nums[right] != 0) {
if (left != right) {
nums[left] = nums[right];
}
left++;
}
right++;
}
while (left < nums.length) {
if (nums[left] != 0) {
nums[left] = 0;
}
left++;
}
}
}
// @lc code=end
四、总结:
此次双指针,left
和righ
t指向了两个数组,不同之处是:
- 思路1是创建了临时数组,
for循环
一次 - 思路2是在原数组上抽象了一个不存在的数组,需要
while循环
两次,第一次left
记录了不为0
的个数,第二次从nums[left]
开始,将非0元素全部置为0