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