题目:
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]
.
思路:
与http://blog.csdn.net/lanxu_yy/article/details/11694125类似。方法1:遍历的时候记录重复的元素次数,如果重复则跳过。记录重复元素的方法可以用包含数值的Hash表或者两个BitMap。由于要保持输出数组的有序性,当非重复数值的时候我们尽量将数值前移。方法2:快慢索引。
代码:
方法1:
class bitmap {
public: bitmap(int n);~bitmap();
void set(int k);
bool val(int k);
private: int len;
unsigned int * map;
unsigned int * reversemap;
bool zero;
};
bitmap::bitmap(int n) {
len = n / 32 + 1;
map = new unsigned int[len];
reversemap = new unsigned int[len];
for (int i = 0; i < len; i++) {
map[i] = 0;
reversemap[i] = 0;
zero = false;
}
}
void bitmap::set(int k) {
bool reverse = true;
if (k == 0) {
zero = true;
} else if (k < 0) {
reverse = false;
k = -k;
}
int a = k / 32;
int b = k % 32;
if (a >= len) {
return;
} else {
if (reverse) {
int tmp = reversemap[a] / pow(2, b);
if (tmp % 2 == 0) {
reversemap[a] += pow(2, b);
}
} else {
int tmp = map[a] / pow(2, b);
if (tmp % 2 == 0) {
map[a] += pow(2, b);
}
}
}
}
bool bitmap::val(int k) {
bool reverse = true;
if (k == 0) {
return zero;
} else if (k < 0) {
reverse = false;
k = -k;
}
int a = k / 32;
int b = k % 32;
if (a >= len) {
return false;
} else {
if (reverse) {
int tmp = reversemap[a] / pow(2, b);
if (tmp % 2 == 1) {
return true;
} else {
return false;
}
} else {
int tmp = map[a] / pow(2, b);
if (tmp % 2 == 1) {
return true;
} else {
return false;
}
}
}
}
class Solution {
public:
int removeDuplicates(int A[], int n) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
bitmap* exist = new bitmap(32767);
bitmap* duplicate = new bitmap(32767);
int count=0;
int skip = 0;
for(int i = 0; i < n; i++)
{
if(duplicate->val(A[i]))
{
skip++;
count++;
}
else if(exist->val(A[i]))
{
duplicate->set(A[i]);
if(skip > 0)
{
A[i-skip] = A[i];
}
}
else
{
exist->set(A[i]);
if(skip > 0)
{
A[i-skip] = A[i];
}
}
}
return n-count;
}
};
方法2:
class Solution {
public:
int removeDuplicates(int A[], int n) {
if(n == 0){
return 0;
}
int slow = 0;
int fast = 1;
while(fast < n){
if(slow > 1 && A[slow-2] != A[fast] && A[slow-1] == A[fast] && A[slow] == A[fast])
{
// ignore
}
else if(slow == 1 && A[slow-1] == A[fast] && A[slow] == A[fast]){
// ignore
}
else{
A[++slow] = A[fast];
}
fast++;
}
return slow + 1;
}
};