您的位置:首页 > 其它

LeetCode 80. Remove Duplicates from Sorted Array II(有序数组移除重复数字Ⅱ)

2018-03-26 20:16 246 查看
题目描述:
    Follow up for "Remove Duplicates": what if duplicates are allowed at most twice?
    For example, given sorted array nums = 
[1,1,1,2,2,3]
.
    Your function should return length = 
5
, with the first five elements of nums being 
1
1
2
2
 and 
3
. It doesn't matter what you leave beyond the new length.
分析:
    题意:给定一个有序重复整型数组,移除重复数字(每个重复数字最多保存两个),从原数组开始位置按序保存结果,并返回新的长度。
    思路:这道题可以采用两种方法:
    ① 用map统计数组所有元素的频数,若某元素出现小于等于两次,都按序加入答案中;否则按序将两个该元素加至答案中。
    ② 我们假设数组原始长度为n,初始化s = 0(保存数组后续跟当前元素不重复的元素的加入位置),e = 1(从左往右扫描过程中的元素下标),d = 0(已经删除的当前出现的重复数字个数),ans = 0(保存新的长度答案)。如果nums[e] == nums[s],那么数字重复,e加一,直到跳出重复统计循环;Ⅰ. 如果e - s > 2,则ans加2、s加2,保存两个当前数字,后续不重复数字(共计n - d - e个)左移至s处,此时d加上(e - s),e = s + 1;Ⅱ. 如果e - s小于等于2,那么后续不重复数字不需要左移(因为不需要删除多余的重复数字),则ans加上(e - s)、s = e、e = s + 1。
    方法①借助map思路更清晰,方法②节省了空间开销。
    两种方法的时间复杂度均为O(n)。

代码(map):
#include <bits/stdc++.h>

using namespace std;

class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size() == 0){
return 0;
}
map<int, int> m;
// count the frequencies
for(int val: nums){
m[val]++;
}
int indices = 0;
for(auto &p: m){
int cnt = min(p.second, 2);
while(cnt--){
nums[indices++] = p.first;
}
}
return indices;
}
};代码:
#include <bits/stdc++.h>

using namespace std;

class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if(n <= 2){
return n;
}
int s = 0, e = 1, d = 0;
int ans = 0;
while(s < e && e <= n - d){
while(e < n - d && nums[e] == nums[s]){
e++;
}
// cout << "s: " << s << ", e: " << e << ", d: " << d << endl;
if(e - s > 2){
ans += 2;
s += 2;
for(int i = e, j = s; i < n - d; i++, j++){
nums[j] = nums[i];
}
d += (e - s);
e = s + 1;
}
else if(e - s <= 2){
ans += (e - s);
s = e;
e = s + 1;
}
}
// cout << "ans: " << ans << endl;
return ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C LeetCode Map Array
相关文章推荐