有序数组原地消重
思路:
所谓消重,有两种方式:
- 字面意思:消去重复的。
- 检出不重复的,这里采用这一种方法。
solution 1
一旦遇到不同的数字,就存到A的前面即可。
class Solution {
public:
int removeDuplicates(int A[], int n) {
//特殊处理n=0的情况
if(n==0){
return 0;
}
//初始化,相当于手动处理了第一个,接下来从A[1]开始存
int last = A[0];
int new_len=1;
for(int i=0;i<n;i++){
int temp = A[i];
if(temp!=last){ //遇到不一样的,存下来
A[new_len] = temp;
new_len++;
}
last = temp;
}
return new_len;
}
};
solution 2
类似于1,但是不用处理n=0的情况
class Solution {
public:
int removeDuplicates(int A[], int n) {
//使得A[0]和last必然不同,接下来从A[0]开始存
int last = A[0]-1;
int new_len=0;
for(int i=0;i<n;i++){
int temp = A[i];
if(temp!=last){
A[new_len] = temp;
new_len++;
}
last = temp;
}
return new_len;
}
};
soulution 3
这个方法陷入了题目的字面意思,也就是第一种思路,消重,效率很低。没有通过。
但是也有能学到东西的地方。
class Solution {
public:
//检测相同的数目,sameCount,往前移动 sameCount-1
int removeDuplicates(int A[], int n) {
int last = A[0];
int sameCount = 0;
int new_len = n;
for (int i = 0; i < new_len; i++){ //new_len不停在变化
int temp = A[i];
if (temp == last && i!=new_len-1){ //看是不是最后
sameCount += 1;
}
else if (temp == last && i == new_len - 1){ //如果是最后,就返回
sameCount += 1;
int dis = sameCount - 1;
new_len -= dis;
return new_len;
}
else if (sameCount != 1){ //如果遇到新的数字,而且之前一个数目不为1,就往前挪。
int dis = sameCount - 1;
int dest = i - dis;
moveForward(A, n, i, dest);
new_len -= dis;
i -= dis; //注意这里 i也要往随着A前挪,不然就乱了
sameCount = 1;
}
last = temp;
}
return new_len;
}
private:
//将A数组的[start,:]移动到[dest,:]
void moveForward(int A[], const int n, const int start, int dest){
for (int i = start; i < n; i++){
A[dest] = A[i];
dest++;
}
}
};
总结
为什么有序数组可以这么干,无序数组呢?
对于该题目来说,有序数组的相重的数字都在一起,所以如果把题目换成:相重的数字都在一起的数组原地消重 是一样的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。