今天起开一个小白刷算法专栏,可能复杂度不是最高的,但是首先要保证自己能做出来,帮助自己对代码和算法要熟悉,也将自己的思路给想学好代码的人提供。
双指针——移动零(283)
栈做:
这题我想到的用栈做,首先写出下面这段代码
import java.util.Stack;
class Solution2 {
//nums = [0,1,0,3,12],输出:[1,3,12,0,0]
//这个我想到了用栈去做,不是0就入栈,是0就最后入栈,补0
public void moveZeroes(int[] nums) {
Stack<Integer> stack=new Stack<>();
//补0,就得统计0的个数
int CountZeros=0;
for (int i = 0; i < nums.length; i++) {
if(nums[i]!=0){
stack.push(nums[i]);
}else {
CountZeros++;
}
}
//现在就要还原这个数组,把栈里的元素按顺序弹出来
//但是栈它是后进先出啊
int index=0;
while (!stack.isEmpty()){
nums[index]=stack.pop();
index++;
}
//补0,补几个0就是补CountZeros的个数
//上面就是走到nums[index]了,几个CountZeros,补几个0
for (int i = 0; i < CountZeros; i++) {
nums[index]=0;
index++;
}
}
}
思路讲解:
1.首先我想到了用栈去做,不是0就入栈,是0就最后入栈,补0
2.既然要补0,就得统计0的个数
3.当非0的入到栈里了,现在就要还原这个数组,把栈里的元素按顺序弹出来
4.但是实际运行时候发现报错了,栈的话是后进先出,比如stack.pop()先弹出来的是后面的12,3,1;再补0 [12,3,1,0,0]
5.所以用栈没法做出来
数组:
再来一个数组做:栈不行,我就用新数组按顺序做,这次成功了
class Solution2 {
//nums = [0,1,0,3,12],输出:[1,3,12,0,0]
//这个我想到了用栈去做,不是0就入栈,是0就最后入栈,补0
//现在完善一下,用新数组去做
public void moveZeroes(int[] nums) {
int[] nums2=new int[nums.length];
//nums[i]遍历一遍,非0的数就按顺序放到新nums2[]里面
//记录非0的个数
int nonCountZeros=0;
for (int i = 0; i < nums.length; i++) {
if (nums[i]!=0){
nums2[nonCountZeros]=nums[i];
//这个nonCountZeros++必须在if里面,只有这样nums2[nonCountZeros]才会自增,新数组才会有值,否则所有不为0的值都会覆盖到nums2[0]的位置
nonCountZeros++;
}
}
//后面补0
for (int i = nonCountZeros; i < nums.length; i++) {
nums2[i]=0;
}
//新数组返还给原数组
for (int i = 0; i < nums.length; i++) {
nums[i]=nums2[i];
}
}
}
思路讲解:
1.现在完善一下,用新数组去做
2.nums[i]遍历一遍,非0的数就按顺序放到新nums2[]里面
3.记录非0的个数,后面补0
4.新数组返还给原数组。
双指针
这回看一个正规做法,其实和上面那个数组差不多,只不过它不用数组了
class Solution {
//正规双指针
public void moveZeroes(int[] nums) {
int nonCountZeros=0;
for (int i = 0; i < nums.length; i++) {
if (nums[i]!=0) {
nums[nonCountZeros] = nums[i];
nonCountZeros++;
}
}
//填充后面的位置
for (int i = nonCountZeros; i < nums.length; i++) {
nums[i]=0;
}
}
}
思路讲解:
1.其实和数组很像,但是这里不需要引入数组
2.当非0的数确认了,后面的数变为0即可
注意:
有一个问题我要理清一下, for (int i = nonCountZeros; i < nums.length; i++) 第二个循环不是从nonCountZeros+1开始,就是从nonCountZeros开始。因为nonCountZeros的值表示了非零元素的个数,所以它指向了后一个元素
- 初始状态:[0, 1, 0, 3, 12],nonCountZeros=0
- 遍历到元素1:由于1不为零,将其移到位置0,nonCountZeros加一变为1。数组变为:[1, 1, 0, 3, 12],nonCountZeros=1
- 遍历到元素0:由于0为零,跳过不处理,数组保持不变。
- 遍历到元素3:由于3不为零,将其移到位置1,nonCountZeros加一变为2。数组变为:[1, 3, 0, 3, 12],nonCountZeros=2
- 遍历到元素12:由于12不为零,将其移到位置2,nonCountZeros加一变为3。数组变为:[1, 3, 12, 3, 12],nonCountZeros=3
完成第一个循环后,数组的前三个位置 [1, 3, 12] 已经被移动成了非零元素。