26.删除排序数组中的重复项(标记量和双指针两种方法)

标记量确定覆盖的下标

解题思路
一层for循环,每次循环通过标记量j确定下一个不等数值要进行赋值的下标(直接覆盖待删除元素)。
时间复杂度:O(n)。
空间复杂度:O(1)。

class Solution {
    public int removeDuplicates(int[] nums) {
        int j=0;//记录删除的个数==赋值时下标减少的值+1
        for(int i=0;i<nums.length;i++){
            while(((i+1)<nums.length)&&nums[i]==nums[i+1]){  //注意边界长度
                i++;
                j++;
            }
            if((i+1)<nums.length)
                nums[i-j+1]=nums[i+1];//每次for循环把下一个不等数值赋过来
            
        }
        return nums.length-j;
    }
}

参考其它:

快慢指针

有序数组的相邻数值可能重复。删除重复元素即将不重复的元素移到数组的左侧。

用2 个指针,一个在前记作 p,一个在后记作 q。算法流程如下:

  1. 比较 p 和 q 位置的元素是否相等。
  2. 如果相等,q 后移 1 位
  3. 如果不相等,将 q 位置的元素复制到 p+1 位置上,p后移一位,q 后移 1 位
  4. 重复上述过程,直到 q 等于数组长度。
  5. 最终返回 p + 1,即新数组长度。
public int removeDuplicates(int[] nums) {
    if(nums == null || nums.length == 0) return 0;
    int p = 0;
    int q = 1;
    while(q < nums.length){
        if(nums[p] != nums[q]){
            if(q - p > 1){
                nums[p + 1] = nums[q];
            }
            p++;
        }
        q++;
    }
    return p + 1;
}

优化
考虑到数组移动的资源消耗是很大的,在本题中每发现一个新数值后进行一次覆盖赋值的优化方法是非常直接的。

你可能感兴趣的:(#)