算法—双指针1.2
🌿力扣283-移动零
🧊题目链接:https://leetcode.cn/problems/move-zeroes/description/
🧊题目描述:
🧊题目分析:
该题可以用两个“指针”去操作数组,dest指针记录已处理区间的最后一个元素下标,cur去遍历数组,如果发现是非0的元素,就配合dest指针来操做数组,没有就继续往后遍历,然后注意下dest和cur啥时候++就行
🧊解题代码:
class Solution {public void moveZeroes(int[] nums) {int dest=-1,cur=0;for(cur=0;cur<nums.length;cur++){if(nums[cur]!=0){swap(nums,dest,cur);dest++;}}}public void swap(int[] nums,int dest,int cur){int i = nums[dest+1];nums[dest+1]=nums[cur];nums[cur]=i;}
}
🧊笔记:
🌿力扣1089-复写零
🧊题目链接:https://leetcode.cn/problems/duplicate-zeros/
🧊题目描述:
🧊题目分析:
首先复写零,我们可能第一时间想的是两个指针dest,cur;cur用于记录复写零之后最后一个数,dest来判断数组的遍历情况
而cur指针从前往后遍历,遇到0就dest走两步,否则就dest就走一步的意思,
然后找到了复写零之后最后一个数,再从后往前复写,关键就在这,上面的逻辑没错,但忽略了dest指针超出数组这一情况,如果不处理,就会影响到这个从后往前复写的操作!!这很重要!!
dest指针超出数组这一情况如下:
可是cur指针也越界了,我们可不希望dest和cur指针越界,希望能正常进行从后往前复写零的操作!
所以我们先这样,每次不先cur++;而是先让dest先走,走完之后,再判断dest到没到数组的组后一个位置,到了就cur不--了,因为cur所指的位置已经是最后一个复写零的位置了,
但是吧,dest确实也存在越界的情况!!如下
我们期望这样,可是不符合我们的逻辑,我们不可捡了芝麻丢了西瓜!!所以另外处理!!
所以需要走完循环之后,来个if语句判断,如果dest超出数组了,就所以dest往回退两步,cur也往回退一步,并且最后一个数组的值置为0!!这个也不叫多么容易想出的逻辑,需要自己动手总结!!
所以我们花了很大的篇幅就是为了解决dest和cur越界的这两种情况!
总结两点:
1.找最后一个复写零时,记得dest可以先走,没事,但cur走的时候,需要判断dest的位置是否已经>=数组的最后一个位置,成立cur就不走了,并退出循环,也就是cur如今的位置就是复写零的最后一个位置
2.退出循环后,我们发现dest有可能越界,毕竟它走两步,万一它是走往两步之后才判断越界而退出循环的呢,所以需要特殊处理,具体的操作其实也就是自己实操,去发现规律,然后处理到位
🧊解题代码:
class Solution {public void duplicateZeros(int[] arr) {int dest=-1,cur=0;//找到最后一个元素下标while(true){//其实true和cur<arr.length都行,反正在如今的逻辑里cur不可能越界if(arr[cur]==0){dest+=2;}else{dest++;}if(dest>=arr.length-1){break;}cur++;//一定要后给cr++,这点很重要}//排除另外一种情况,也就是超出数组的那个情况if(dest!=arr.length-1){arr[arr.length-1]=0;dest-=2;cur--;}//复写操作for(;cur>=0;cur--){if(arr[cur]==0){arr[dest--]=0; arr[dest--]=0;}else{arr[dest--]=arr[cur];}}}
}
🧊笔记:
本来想直接想多道题的,可是这第2个题,也确实花了不少时间!!下篇再分享吧!完结!!