LeetCode 80 Remove Duplicates from Sorted Array II

166 阅读2分钟

LeetCode 80 Remove Duplicates from Sorted Array II

思路

  1. 三个指针,i,j,k。每次循环,j指针都要向后移动一次,k指针指向当前值的一个,i指针指向需要被替换的元素。当j和k指向的值相等时,判断j和k的距离,如果距离大于1,则j与k之前的重复元素大于等于3个,此时j指针继续向前走,i指针位置不变。j一直向前走到一个新值,然后更新k,并用新值替换i指向的元素。如果距离小于等于1,说明j指向的元素是合法的,于是用j指向的元素覆盖i指向的元素,并且i指针和j指针都往前走。

  2. 两个指针i和j。j指向目前检查的元素,i指向目前需要被覆盖的元素。当i < 2时,说明此时正在遍历前k个元素,直接覆盖本身即可。当i >= 2 && nums[j] > nums[i-2]时,说明找到一个新值来覆盖当前元素nums[i]。当i >= 2 && nums[j] <= nums[i-2]时,说明从i-2到j之间已经出现3个或3个以上的重复元素,因此,i不变,直到找到一个新值覆盖i指向的元素。

此题可以推广至一般情况,若最多只能有k个重复元素。

代码

方法一:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if (nums.size() < 3) return nums.size();
        int len = 0, i = 0, j = 0, k = 0;
        
        for (; j < nums.size(); ++j) {
            if (nums[j] == nums[k]) {
                if (j < k + 2) {
                    nums[i] = nums[j];
                    ++i;
                }
                else {
                    while (j + 1 < nums.size() && nums[j+1] == nums[j]) ++j;
                }
            }
            else {
                nums[i++] = nums[j];
                k = j;
                
            }
        }
        
        return i;
    }
};

方法二:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int i, j ;
        
        for (i = 0, j = 0; j < nums.size(); ++j) {
            if (i < 2 || nums[j] > nums[i-2])
                nums[i++] = nums[j];
        }
        
        return i;
    }
};

推广:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int i, j ;
        
        for (i = 0, j = 0; j < nums.size(); ++j) {
            if (i < k || nums[j] > nums[i-k])
                nums[i++] = nums[j];
        }
        
        return i;
    }
};