【題目】1089. 複寫零
給你一個長度固定的整數數組 arr,請你將該數組中出現的每個零都複寫一遍,並將其餘的元素向右平移。
注意:請不要在超過該數組長度的位置寫入元素。
要求:請對輸入的數組 就地 進行上述修改,不要從函數返回任何東西。
示例 1:
輸入:[1,0,2,3,0,4,5,0]
輸出:null
解釋:調用函數後,輸入的數組將被修改爲:[1,0,0,2,3,0,0,4]
示例 2:
輸入:[1,2,3]
輸出:null
解釋:調用函數後,輸入的數組將被修改爲:[1,2,3]
提示:
1 <= arr.length <= 10000
0 <= arr[i] <= 9
【解題思路1】快慢指針
class Solution {
public void duplicateZeros(int[] arr) {
int len = arr.length;
int fast = 0, slow = 0; //i是快指針,j是慢指針
while(fast < len){
if(arr[slow] == 0){
fast++;
}
fast++;
slow++;
}
slow--; //要複製的最後一個數的下標,這之後的數溢出
if(fast != slow){ //有0
int i = len - 1;
//處理最後一個元素是0,複製這個0溢出的情況,如[1,0,2,3,0,0,5,0]
if(fast == len + 1){
arr[i] = 0;
i--;
slow--;
}
while(slow >= 0){
if(arr[slow] == 0){
arr[i] = 0;
arr[i - 1] = 0;
i--;
}else{
arr[i] = arr[slow];
}
i--;
slow--;
}
}
}
}
class Solution {
public void duplicateZeros(int[] arr) {
int n = arr.length;
int i = 0, j = 0;
while (j < n) {
if (arr[i] == 0) ++j;
++i;
++j;
}
--i; // i 回到最後一次合法的位置
--j; // j 同理,但 j 仍可能等於 n(例如輸入 [0])
while (i >= 0) {
if (j < n) arr[j] = arr[i];
if (arr[i] == 0) arr[--j] = arr[i];
--i;
--j;
}
}
}
【解題思路2】複製數組 - 輔助數組
class Solution {
public void duplicateZeros(int[] arr) {
int[] temp = Arrays.copyOf(arr, arr.length);//複製原數組到temp
int index = 0;//指向temp的數組下標
for(int i = 0; i < arr.length; i++){//修改原數組(只要把原數組修改完就行,temp數組可能未遍歷完)
arr[i] = temp[index];//將temp[index]的值直接給arr[i]
if(temp[index++] == 0 && i+1 < arr.length){//如果temp[index]==0的話,考慮補0
arr[i+1] = 0;
i++;
}
}
}
}