给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
1. 暴力法
从后往前遍历,碰到0将所有元素后移,即再从后往前遍历一次
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int n = arr.size();
for(int i =n-1;i>=0;i--){
if(arr[i]==0){
for(int j=n-1;j>i;j--){
arr[j] = arr[j-1];
}
}
}
}
};
2. 双指针模拟栈
其实就是先计算有多少个零需要复写,求复写区间,然后做复写区间到全区间的映射
先从前往后求区间,再从后往前做映射,相比暴力法减少了重复遍历
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int n = arr.size();
int top = 0;//栈顶
int i = -1;//遍历数组指针
while (top < n) {//其实目的就是记录能复写的0的个数
i++;
if (arr[i] != 0) {//栈顶移动一格
top++;
} else {
top += 2;//栈顶移动两格,里面包含的数由数组指针前的数组成
}
}//出循环后得到位置i,i后面数皆被挤出
int j = n - 1;//指针从数组末位置开始
if (top == n + 1) {//如果i位置为0
arr[j] = 0;//移动过去,无需复写
j--;//右指针前移
i--;//左指针前移
}
while (j >= 0) {//
arr[j] = arr[i];//移动元素
j--;//右指针前移
if (!arr[i]) {//判断左指针是否为零
arr[j] = arr[i];//复写
j--;//右指针前移
}
i--;//左指针前移
}
}
};
原创文章,作者:端木书台,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/268108.html