Leetcode--283. 移动零
Leetcode--283. 移动零
给定一个数组
nums
,编写一个函数将所有0
移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例1
// 快慢指针+小优化
class Solution {
public void moveZeroes(int[] nums) {
int slow = 0;
for(int fast = 0; fast < nums.length; fast++) {
if(nums[fast] != 0) {
// 这里主要是将指向i和j的元素进行交换
if(nums[slow] != nums[fast]) {
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
}
slow++; // 注意一定不能忘记这里需要++
}
}
return;
}
}
这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点 x,然后把所有小于等于 x 的元素放到 x 的左边,大于 x 的元素放到其右边。
这里我们可以用 0 当做这个中间点,把不等于 0(注意题目没说不能有负数)的放到中间点的左边,等于 0 的放到其右边。 这的中间点就是 0 本身,所以实现起来比快速排序简单很多,我们使用两个指针 fast 和 slow,只要 nums[i]!=0,我们就交换 nums[i] 和 nums[j]
i和j的相对位置是:【已经处理好的数据】slow【全是需要被交换的0】fast【未处理的数据】。 然后i始终去找非0的数据进行交换,每次交换完,j的位置变成处理好的非0数据向后移动一个位置,等待i找到下一个需要交换的非0数据
我的笨办法:
参考冒泡排序,将0与后面对换,但是缺点是双重循环且循环次数最多为nums.length的阶乘,效率低下
class Solution {
public void moveZeroes(int[] nums) {
int tmp = 0;
int count = nums.length - 1;
for (int j = 0; j < count; j++) {
for (int i = 0; i < count - j; i++) {
tmp = nums[i + 1];
if (nums[i] == 0) {
nums[i + 1] = nums[i];
nums[i] = tmp;
}
}
}
}
}