引言
在今天的文章中,我们将深入解析一个既经典又富有挑战性的算法问题——“复写零”。这个问题不仅考验着我们对数组操作的理解,还促使我们探索高效的解决方案,特别是通过双指针技巧来优化算法。想象一下,你有一个整数数组,任务是将数组中的所有零元素复制一份,并将它们以及原有的非零元素重新排列,同时保持非零元素的相对顺序不变,而且这一切都需要在数组的原址上进行,不能使用额外的数组空间。这正是我们今天要解决的难题。
leetcode-复写0
问题描述
给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。
示例:
示例 1:
输入:arr = [1,0,2,3,0,4,5,0]
输出:[1,0,0,2,3,0,0,4]
解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]
示例 2:
输入:arr = [1,2,3]
输出:[1,2,3]
解释:调用函数后,输入的数组将被修改为:[1,2,3]
解题思路
- 双指针法:先根据“异地”操作,然后优化成双指针下的“就地”操作
1.先找到最后一个"复写"的数
边界情况
2.从后向前,完成复写操作。
代码实现
以下是使用C++实现的代码示例:
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int cur = 0, dest = -1, n = arr.size();
//找到最后复写的位置
while(cur < n){
if(arr[cur]){
dest++;
}else{
dest+=2;
}
if(dest >= n-1) break;
cur++;
}
//边界情况
if(dest == n){
arr[--dest]=0;
cur--;dest--;
}
//从后往前开始复写0
while(cur>=0){
if(arr[cur]){
arr[dest--] = arr[cur--];
}else{
arr[dest--] = arr[cur];
arr[dest--] = arr[cur--];
}
}
}
};