类似题的思路
这一类问题就是数组的移动相关的,我们基本上都是使用双指针的方式来解决,不过题目要求一般都是只能在原数组上进行修改,不能创建新的数组,所以我们的思路主要是根据创建两个数组,两个数组移动变量的情况下,将其转换为一个数组,两个数组移动变量
题目一移动零

思路分析
这个问题的主要思路就是双指针,也就是区域划分,将我们的数组划分为三个区域,第一个区域是全部都是非0,第二个是0,第三个是还未处理的,我们定义两个变量,cur跟dest,cur从左往右遍历数组,dest最开始指向-1,dest接下来的目标是指向处理过的元素中的非零元素的最后一个,当我们cur指向的元素非0的时候,就先让我们的dest++,加加完指向的就是第一个0,然后将nums[dest]以及nums[cur]进行交换,然后一直这样,直到cur走完
思路图

代码展示
class Solution {
public void moveZeroes(int[] nums) {
int cur=0;
int dest=-1;
for(cur=0;cur<nums.length;cur++){
if(nums[cur]!=0){
dest++;
//进行交换
swap(cur,dest,nums);
}
}
}
public void swap(int cur,int dest,int[] nums){
int tmp=nums[cur];
nums[cur]=nums[dest];
nums[dest]=tmp;
}
}
题目二复写零

思路分析
这个问题的主要思路就是双指针,不过我们不能直接从前往后进行复写,因为如果从前往后复写的话,就有可能会将后面还没有处理到的元素覆盖掉,所以我们这道题的思路就是先找到最后一个需要复写的数,然后再从后往前进行复写。我们定义两个变量 cur 和 dest,cur 从数组的第一个元素开始向后遍历,dest 最开始指向 -1,当 cur 指向的元素是非0的时候,就让 dest++,因为非0元素只需要占一个位置;当 cur 指向的元素是0的时候,就让 dest += 2,因为0需要被复写一次,也就是占两个位置。一直这样向后遍历,直到 dest 到达或者超过数组的最后一个位置,此时 cur 指向的就是最后一个需要处理的元素。
但是这里可能会出现一种特殊情况,就是 dest 恰好越界一个位置,这说明当前 cur 指向的一定是0,并且这个0复写之后只有一个0能够放进数组中,所以我们先直接将数组最后一个位置设置为0,然后让 cur--,dest -= 2,再继续后面的操作。
找到最后一个需要处理的元素之后,我们就开始从后往前进行复写。如果 cur 指向的是非0元素,就直接将 nums[cur] 放到 nums[dest] 中,然后 cur--、dest--;如果 cur 指向的是0,就需要在 dest 和 dest - 1 两个位置都放入0,然后让 cur--、dest -= 2。一直这样从后往前进行处理,直到 cur 走完,此时数组中的0就全部完成复写,并且也不会覆盖还没有处理到的元素。
思路图

代码展示
class Solution {
public void duplicateZeros(int[] arr) {
//先通过双指针来找到最后一个复写数
int cur=0;
int dest=-1;
int n=arr.length;
while(cur<n){
if(arr[cur]!=0){
dest+=1;
}else{
dest+=2;
}
if(dest>=n-1){
break;
}
cur++;
}
// 特殊情况:最后一个0只能放进去一份
if (dest == n) {
arr[n - 1] = 0;
cur--;
dest -= 2;
}
while(cur>=0){
if(arr[cur]!=0){
arr[dest--]=arr[cur--];
}else{
arr[dest--] =0;
arr[dest--] =0;
cur--;
}
}
}
}
364



被折叠的 条评论
为什么被折叠?



