Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
For example,
Given input array A = [1,1,2]
,
Your function should return length = 2
, and A is now [1,2]
.
思路:
我用两个游标分别记录新数组的下一个位置newpos和原数组要判断的下一个位置pos。如果pos位置的数字和newpos - 1 的一样则跳过
关键:比较是否一样时与新的数组的目前最后一个数字比。
int removeDuplicates(int A[], int n) { if(n == 0) return 0; int newpos = 1, pos = 1; while(pos < n) { if(A[pos] == A[newpos - 1]) pos++; else A[newpos++] = A[pos++]; } return newpos; }
大神超短的代码:
int count = 0; for(int i = 1; i < n; i++){ if(A[i] == A[i-1]) count++; else A[i-count] = A[i]; } return n-count;
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]
.
允许两个重复的
思路:与上面其实都一样,就是把判断条件改为与上两个数字相同就跳过。注意,要与新数组最后两个数字比较。
int removeDuplicatesTwice(int A[], int n) { if(n <= 2) return n; int pos = 2; //新数组的下一个判断位置 for(int i = 2; i < n; i++) { if(!(A[i] == A[pos - 1] && A[i] == A[pos - 2])) //这里是关键,要和pos-1 和 pos-2比较。pos对应的出现两次才是真的两次了。不能和i-1和i-2比,因为可能在前面这两个位置的数字已经改变了。 { A[pos++] = A[i]; } } return pos; }
有人写了一个问题泛化到可以重复k次的代码:
int removeDuplicates(int A[], int n, int k) { if (n <= k) return n; int i = 1, j = 1; int cnt = 1; while (j < n) { if (A[j] != A[j-1]) { //其实我觉得这里写成A[j] != A[i - 1] 更好 cnt = 1; A[i++] = A[j]; } else { if (cnt < k) { A[i++] = A[j]; cnt++; } } ++j; } return i; }