欢迎来到 CILMY23的博客
🏆本篇主题为:双指针算法之 1089.复写零(力扣)
🏆个人主页:CILMY23-CSDN博客
🏆系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题 | 代码训练营
🏆感谢观看,支持的可以给个一键三连,点赞关注+收藏。
✨写在前头:
1089. 复写零 - 力扣(LeetCode)
题目
给你一个长度固定的整数数组 arr
,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。
一、题目解析
通过题目我们可知:
- 整数数组
arr
是长度固定的- 该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
- 不要在超过该数组长度的位置写入元素
- 就地修改
- 不返回任何东西
二、算法原理
暴力解法
我的想法是这样的,假设有个i指向数组的左边,假设有个j指向数组的右边。
我先每次都让i往右走,直到i找到0
然后我开始从j位置,每次都让前面的位置向后移动。
直到 j == i的时候,让这个位置的数,添加0,就算复写0了。
然后这个时候i就不可以++了,而是加2.
然后j再从右边开始。
双指针算法
其实我的想法好像相差无几,这是一个从后向前的同向双指针
第一步:找到最后一个“复写”的数
定义两个指针,一个是cur 指向数组最左边,一个是dest 指向-1,当 cur 所指向的位置不为0时,dest前进1,当cur 指向0时候,这时候dest就要前进2步。
遍历完后:
特殊情况:
dest可能越界:
如何处理?
也就是在越界的地方我们并不修改,对n-1的地方进行修改为0,然后cur前进一步,dest 前进两步。
第二步:
然后进行复写操作 即可,当cur指向不为0的时候,dest拷贝一个,cur指向0的时候,拷贝一个0.
三、代码编写
暴力解法:
class Solution {
public:void duplicateZeros(vector<int>& arr) {int n = arr.size() - 1;int i = 0;int j = n;while(i <= n){if(arr[i]!=0) //找0{i++;}else{j = n; //每次j都要从右边开始while(i < j){arr[j] = arr[j -1];j--;}arr[i] = 0;i += 2;}}}
};
双指针算法:
class Solution {
public:void duplicateZeros(vector<int>& arr) {// 1. 找到最后一个复写的数int cur = 0;int dest = -1;int n = arr.size();while(cur<n){if(arr[cur] != 0 ){dest++;}else{dest+=2;}if(dest >= n-1){break;}cur++;}//1.5//处理边界情况if(dest == n){arr[n-1] = 0;cur--;dest -= 2;}//2.完成复写while(cur>=0){if(arr[cur] != 0 ){arr[dest] = arr[cur];dest--;cur--;}else{arr[dest--] = 0;arr[dest--] = 0;cur--;}}}
};
🛎️感谢各位同伴的支持,本期C++就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞,关注+收藏,若有不足,欢迎各位在评论区讨论。