1089. Duplicate Zeros*
https://leetcode.com/problems/duplicate-zeros/
题目描述
Given a fixed length array arr
of integers, duplicate each occurrence of zero, shifting the remaining elements to the right.
Note that elements beyond the length of the original array are not written.
Do the above modifications to the input array in place, do not return anything from your function.
Example 1:
Input: [1,0,2,3,0,4,5,0]
Output: null
Explanation: After calling your function, the input array is modified to: [1,0,0,2,3,0,0,4]
Example 2:
Input: [1,2,3]
Output: null
Explanation: After calling your function, the input array is modified to: [1,2,3]
Note:
1 <= arr.length <= 10000
0 <= arr[i] <= 9
C++ 实现 1
这题如果用额外的空间, 那特别好做. 现在我们只考虑 in-place
的做法.
先看一种实现特别慢的. 最后只 beats 5%
🥺, 但思路直观. 向后移动元素.
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
for (int i = 0; i < arr.size() - 1; ++ i) {
if (arr[i] == 0) {
for (int j = arr.size() - 2; j > i; -- j)
arr[j + 1] = arr[j];
arr[++i] = 0;
}
}
}
};
C++ 实现 2
进一步思考🤔. 我们用例子来介绍, 比如 arr = [1,0,2,3,0,4,5,0]
, 如果只考虑 0
的复制, 那么数组将变成:
复制前: 1 0 2 3 0 4 5 0
复制后: 1 0 0 2 3 0 0 4 5 0 0
原本数组可能变成 11
个元素, 但由于原数组大小只有 8
, 所有最后 3
个元素要被丢弃. 被利用到的数只有 1 0 2 3 0 4
. 那是不是就可以用一个指针 k
来指向最后所需要的元素的范围, 比如此时 k
应当指向 4
. 因此下面代码中:
// 注意 k 初始化为 -1
for (int i = 0; i < arr.size(); ++ i) {
if (arr[i] == 0) count += 2;
else count += 1;
++ k;
if (count >= arr.size()) break;
}
作用就是确定会用到的数据的范围. 之后只需要将 1 0 2 3 0 4
按规则正确地放置在 arr
中. 遇到 0
则放置两个 0
. 但其中有一点要注意, count
可能会大于 arr.size()
, 比如能用的数据最后一个为 0
, 但这个 0
不必复制. 比如 arr = [1, 2, 0]
. 这种特殊情况应该考虑. 下面代码使用:
if (count > arr.size() && j == arr.size() - 1) continue;
处理这种情况. 此种做法最后 beats 98%
.
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int k = -1, count = 0;
for (int i = 0; i < arr.size(); ++ i) {
if (arr[i] == 0) count += 2;
else count += 1;
++ k;
if (count >= arr.size()) break;
}
for (int j = arr.size() - 1; j >= 0; -- j) {
if (arr[k] != 0) arr[j] = arr[k--];
else {
arr[j] = arr[k--];
if (count > arr.size() && j == arr.size() - 1) continue;
if (j - 1 >= 0) arr[--j] = 0;
}
}
}
};
扩展阅读
在 LeetCode Submission 看到的一种方法, 没有细看, 以后有机会再去详细理解 ⛳.
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int cntz = 0;
int n = arr.size();
for(int i = 0; i < arr.size(); i++) {
if(arr[i] == 0) cntz++;
}
int pos = cntz + n - 1;
for(int i = n - 1; i >= 0; i--) {
if(pos < n) arr[pos] = arr[i];
if(arr[i] == 0) {
pos--;
if(pos < n) arr[pos] = 0;
}
pos--;
}
}
};