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 =
Your function should return 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;
}
};
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,
2and
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;
}
};
相关文章推荐
- LeetCode 26 Remove Duplicates from Sorted Array (移除有序数组中重复数字)
- leetcode 4. 移除有序数组中的重复元素 Remove Duplicates from Sorted Array
- 移除有序数组中的重复数字
- 每日一题之LeetCode移除元素 删除有序数组重复元素
- LeetCode-Remove Duplicates from Sorted Array-从有序数组移除重复-简单逻辑
- 去掉有序数组中重复数字 原地 leetcode java (最简单的方法)
- Leetcode26:Remove Duplicates from Sorted Array(移除已排序数组中重复的数字)
- Remove Duplicates from Sorted Array II 从有序数组里移除重复出现元素,最多重复出现2次 @LeetCode
- 【leetcode 移除有序序列重复数字】Remove Duplicates from Sorted Array(List) I(II)
- LeetCode 26. Remove Duplicates from Sorted Array(移除有序数组的重复元素)
- leetcode 7. 在有序可重复数组旋转后搜索 Search in Rotated Sorted Array II
- LeetCode 26 Remove Duplicates from Sorted Array(从已排序数组中移除重复元素)
- 每天一道LeetCode-----有序数组循环右移n位后,寻找最小值,数组中可能包含重复元素
- leetcode 217 Contains Duplicate 数组中是否有重复的数字
- [LeetCode] 26. Remove Duplicates from Sorted Array 有序数组中去除重复项
- leetcode:Remove Duplicates from Sorted Array II (允许重复一次,去掉数组多余数字)【面试算法题】
- 已知数组长度为100,且基本有序,里面有仅有两个数字位置不对,但具体是那两个数字不知道,数字不重复
- [LeetCode] 83. Remove Duplicates from Sorted List 移除有序链表中的重复项
- 每天一道LeetCode-----从有序数组中删除重复元素
- leetcode 2. 从有序链表和数组中移出重复元素 Remove Duplicates