題目
Follow up for "Remove Duplicates": What if duplicates are allowed at most twice?
For example, Given sorted array A = [1, 1, 1, 2, 2, 3],
Your function should return length = 5, and A is now [1, 1, 2, 2, 3]
接着移除有序數組裏面的重複數字那道題目,如果允許重複兩次的情況下,應該怎麼處理呢?
例如給你一個有序的數組A = [1, 1, 1, 2, 2, 3],你的函數需要返回長度=5,而且A= [1, 1, 2, 2, 3]
分析
和之前那個題目有點類似哈,只是說允許連續的兩次重複,可以有3種解法:
1. 我們增加一個duplicate的計數器,如果計數器達到給定的值,那麼就不在繼續填充我們新的數組,否則就繼續填充。如果遇到新的值,就更新計數器爲0。
優勢:容易擴展到允許n次重複的情況
劣勢:需要額外維護一個計數器,增加了代碼的複雜度,出錯機率比較大
2. 可以判斷當前值和新數組的上一個值及上上一個值是否相等,如果相等久忽略,否則加入。
優勢:邏輯比較簡單,只需要判斷要遍歷的值和新數組的上一個值及上上一個值是否相等就可以,清晰切不容易出錯。
劣勢:比較難以擴展到允許n次重複的情況
3. 基於方案2的改進策略:由於數據是有序的,如果允許n次重複,那麼我們這個時候只需要判斷當前值是否與新數組的n-1個值是否相等就可以了。
優勢:邏輯簡單清晰,不容易出錯
劣勢:比較難以考慮到,需要分析數據的情況(可以把數據列出來,舉幾個例子總結出來)
代碼
代碼只實現方案1和方案3,方案2大家可以自行實現。
/****************************************
* Follow up for "Remove Duplicates": What if duplicates are allowed at most twice?
* For example, Given sorted array A = [1, 1, 1, 2, 2, 3],
* Your function should return length = 5, and A is now [1, 1, 2, 2, 3]
****************************************/
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
/* Time: O(n), Space: O(1) */
int removeDuplicates1(vector<int> &nums) {
if (nums.empty()) {
return 0;
}
int start = 0;
int duplicate = 1;
for (int i = 1; i < nums.size(); i++) {
if (nums[start] != nums[i] || duplicate < 2) {
if (nums[start] != nums[i]) {
duplicate = 0;
}
start++;
nums[start] = nums[i];
}
duplicate++;
}
for (int i = nums.size() - 1; i > start; i--) {
nums.pop_back();
}
return start + 1;
}
/* Time: O(n), Space: O(1) */
int removeDuplicates2(vector<int> &nums) {
if (nums.empty()) {
return 0;
}
int start = 1;
int duplicate = 2;
for (int i = 2; i < nums.size(); i++) {
if (nums[start - 1] != nums[i]) {
start++;
nums[start] = nums[i];
}
}
for (int i = nums.size() - 1; i > start; i--) {
nums.pop_back();
}
return start + 1;
}
};
int main(void) {
Solution* s = new Solution();
vector<int> nums;
nums.push_back(1);
nums.push_back(1);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
nums.push_back(2);
nums.push_back(3);
nums.push_back(3);
nums.push_back(4);
cout << "Solution 1: " << s->removeDuplicates1(nums) << endl;
for (int i = 0; i < nums.size(); i++) {
cout << nums[i] << ",";
}
cout << endl;
cout << "Solution 2: " << s->removeDuplicates2(nums) << endl;
for (int i = 0; i < nums.size(); i++) {
cout << nums[i] << ",";
}
delete s;
return 0;
}