双指针:26. 删除排序数组中的重复项

这道题开始没思路,但是后来用双指针的分区域法一思考,基本很快就搞出来了。不过一是有个细节搞错了,二是还有很多地方可以优化。

class Solution {
    public int removeDuplicates(int[] nums) {
        //空数组特判
        if(nums.length==0)
        {return 0;}
         int p1=-1,p2=0;//p1指向重复区开头,p2用于遍历
         int lastNum=0;
         while(p2<nums.length)
         {
             if(p2==0)
             {
                 lastNum=nums[0];
                 p2++;
             }
             else
             {
                 if(nums[p2]==lastNum)
                 {  
                     //重复了
                    if(p1==-1)
                    {
                      //开辟重复区
                      p1=p2;
                      p2++;  
                    }
                    else
                    {
                        p2++;
                    }

                 }
                 else if(nums[p2]!=lastNum)
                 {
                    //没有重复,变换,修改lastnum
                    lastNum=nums[p2];
                    if(p1==-1)//
                    {
                        p2++;
                    } 
                    else
                    {
                        int num=nums[p1];
                        nums[p1]=nums[p2];
                        nums[p2]=num;
                        p1++;
                        p2++;
                    }
                 }
             }

         }
         //应该特判假如p1为-1时
         if(p1==-1)
         {return nums.length;}
         else
         {return p1;}
         

    }
} 

代码开始写成这样,第一次错误是一直没有重复项时p1为初值-1。当然有几个p2++可以提出来。

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]){
            nums[p + 1] = nums[q];
            p++;
        }
        q++;
    }
    return p + 1;
}

官方的这种解法当然简洁很多,但感觉没有之前那种套路百试不爽。

本人代码简化后:

class Solution {
    public int removeDuplicates(int[] nums) {
        //空数组特判
        if(nums.length==0)
        {return 0;}
         int p1=nums.length,p2=1;//p1指向重复区开头,p2用于遍历。这里p1初始值设成这个,就不用特判了
int lastNum=nums[0]; while(p2<nums.length) { if(nums[p2]==lastNum) { //重复了 if(p1==nums.length) { //开辟重复区 p1=p2; } } else if(nums[p2]!=lastNum) { //没有重复,变换,修改lastnum lastNum=nums[p2]; if(p1!=nums.length)// { int num=nums[p1]; nums[p1]=nums[p2]; nums[p2]=num; p1++; } } p2++; } //应该特判假如p1为-1时,这里第一次搞错了 return p1; } }
原文地址:https://www.cnblogs.com/take-it-easy/p/13845061.html