LeetCode – Remove Duplicates from Sorted Array II (Java)

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].

So this problem also requires in-place array manipulation.

Java Solution 1

We can not change the given array's size, so we only change the first k elements of the array which has duplicates removed.

```public int removeDuplicates(int[] nums) { if(nums==null){ return 0; } if(nums.length<3){ return nums.length; }   int i=0; int j=1; /*   i, j 1 1 1 2 2 3 step1 0 1 i j step2 1 2 i j step3 1 3 i j step4 2 4 i j   */ while(j<nums.length){ if(nums[j]==nums[i]){ if(i==0){ i++; j++; }else if(nums[i]==nums[i-1]){ j++; }else{ i++; nums[i]=nums[j]; j++; } }else{ i++; nums[i]=nums[j]; j++; } }   return i+1; }```

The problem with this solution is that there are 4 cases to handle. If we shift our two points to right by 1 element, the solution can be simplified as the Solution 2.

Java Solution 2

```public int removeDuplicates(int[] nums) { if(nums==null){ return 0; }   if (nums.length <= 2){ return nums.length; } /* 1,1,1,2,2,3 i j */ int i = 1; // point to previous int j = 2; // point to current   while (j < nums.length) { if (nums[j] == nums[i] && nums[j] == nums[i - 1]) { j++; } else { i++; nums[i] = nums[j]; j++; } }   return i + 1; }```
Category >> Algorithms
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
```<pre><code>
String foo = "bar";
</code></pre>
```
• Alik Elzin

I think it’s easier to understand with a for loop and the notion of `last`.
``` int removeDuplicates(int[] nums) { if (nums == null || nums.length == 0) return 0;```

``` if (nums.length <= 2) return nums.length; int last = 1; for (int i = 2 ; i < nums.length ; ++i) { if ((nums[last] < nums[i]) || (nums[last-1] != nums[last])) { last++; nums[last] = nums[i]; } } ```

``` return last + 1; } ```

• Amr Hendy

``` class Solution { public: int removeDuplicates(vector& nums) { int lastIndex = 0, REP = 2, lastCnt = 1; for(int i = 1; i < nums.size(); i++) { if(nums[i] == nums[lastIndex] && lastCnt == REP) continue; lastCnt = (nums[lastIndex] == nums[i]) * lastCnt + 1; nums[++lastIndex] = nums[i]; } return nums.size() == 0 ? 0 : lastIndex + 1; } }; ```

• xpress razor

My approach is more similar to second. As long as the next element is duplicate you increment the second pointer, if not you can consistently copy value from second pointer to first and move both. Same solution works for version 1 of this problem, where you look at next 1 element, here next 2 elements.

``` int n = nums.length; int i = 0; int j = 0; while (j < n) { while (j + 2 < n && nums[j+2] == nums[j]) { j++; }```

``` nums[i] = nums[j]; j++; i++; } ```

``` return i; ```

• RaveeendraGuntupalli

Array needs to be sorted ? I see The solution works even if the array is not sorted.

• Somya Kajla

public int removeDuplicates(int[] nums) {
int dup_status = 1;
int index = 1;
for(int i = 0; i < nums.length-1; i++){
if(nums[i] != nums[i+1] ){
dup_status = 1;
nums[index ++] = nums[i+1];
}
else if(nums[i] == nums[i+1] && dup_status < 2){
dup_status ++;
nums[index ++] = nums[i+1];
}

}
return index;

}

• Ankit Shah

similar to the duplicates I solution

``` private static int[] removeDuplicateII(int[] a) { if (a.length < 3) return a; int i = 0; int j = 1; int k = 2; while (k < a.length) { if (a[i] == a[j] && a[j] == a[k]) { j++; k++; } else { i++; a[i] = a[j]; j++; a[j] = a[k]; k++; } } ```

``` int[] b = Arrays.copyOf(a, i + 2); return b; } ```

• Larry Okeke

``` public static int remove_duplicates(int[] nums){ int duplicates =0; for(int i = 0; i < nums.length; i++){ if(i < nums.length-1 && nums[i] == nums[i+1]){ int step = i++; while((i < nums.length-1 )&&nums[step] == nums[i++]){ duplicates++; } } } return nums.length - duplicates; ```

``` } ```

• Swathi

How about this? A slight modification on the remove duplicates I

` `

``` int[] removeDuplicatesN(int[] arr, int N){ int i=0,j=1, l=0; int n= arr.length; while(j<n){ if(arr[i]==arr[j]){ j++; l++; if(l<N) i++; } else{ l=0; i++; arr[i] = arr[j]; j++; } } return Arrays.copyOf(arr, i+1); } ```

• cp

the better solution has a little bug. If an array [1,1] then it does not remove the element.

• vincent

Good!

• Liang Tao

I think what you said is the answer for “Remove Duplicates” problem, not this II version.

• TK

class Solution {
public:
int removeDuplicates(int A[], int n) {
int currentPosition = 2;
for (int i = 2; i < n; ++ i)
if (A[i] != A[i-2])
A[currentPosition++] = A[i];
return min(currentPosition, n);
}
};

• claire

great solution

• The better solution is actually confusing. We can make the rule like this:
Assign previous pointer to 1st element(a[0]) and current pointer to 2nd element(a[1]).
1) if a[prev] != a[curr], {prev++; a[prev]=a[cur]; cur++;}
2) else, {cur++;}

you can remove the A[curr] == A[prev – 1] in this case.

• W Han

In the first solution, the loop starts from the second element. If input array has only one element it will cause index out of bounds error.