力扣:删除有序数组中的重复项

双指针思想

当我们在访问线性的数据结构时,往往可以引用两个指针来访问,再根据所给条件来对这两个指针进行对比,移动。在今天的题目中,是以数组为数据结构,我们都知道,数组可以利用下标来进行访问指定元素。所以,我们在数组的双指针就可以利用非指针变量(一般是整型变量)来当作下标,进而当作数组中的指针。
在这里插入图片描述

力扣:26

题目:
在这里插入图片描述
实例:
在这里插入图片描述

思路:我们首先需要遍历这个数组,创建一个新的数组来接收符合条件的元素;接着我们要想怎么给出条件,我们根据所给要求,由于是有序数组,可以判断新数组最后一个元素是否小于当前下标访问的元素,如果是,那么就将它存进新数组中。

int removeDuplicates(int* nums, int numsSize){
    
    
    //创建一个数组接收重组内容
    int new[10000];
    //新数组位移下标
    int cur=0;
    //先对首元素赋值
    new[0]=nums[0];
    //统计长度
    int sum=1;
    //遍历找出符合条件
    for(int i=1;i<numsSize;i++)
    {
    
    
        if(nums[i]>new[cur])
        {
    
    
            new[++cur]=nums[i];
            sum++;
        }
    }
    for(int i=1;i<sum;i++)
    {
    
    
        nums[i]=new[i];
    }
    return sum;

}

在这里插入图片描述

我们这么做,会发现我们利用空间比较多(空间复杂度O(n))。那能不能在节省一些空间呢?答案是肯定的。我们先对上面进行初步优化,我们会发现其实利用下标cur即可表现new数组的长度,只需最后+1就能表示新数组的长度,所以sum变量可以省去。上面放入新数组的条件大于改为不等于,因为实际上就是新数组最后一个元素与当前访问数组不同时,就改变新数组。相同时,那么nums数组继续向前遍历。
由于题目给出条件,不需要考虑数组中超出新长度后面的元素,其实我们就可以在原数组进行这些步骤,即将这两个数组合二为一。我们的其它思路保持不变,这时我们对nums[]创建两个指针,初始化都为1,一个为fast,一个为slow,fast表示访问的下标,对应上面的i,slow表示返回的长度,对应上面的cur+1(也是sum),也表示新数组下一个元素该填的位置;那么nums[slow-1]就表示新数组最后一个元素。这样思路就完成了。当然,还需要考虑一下特殊条件,倘若长度为0,那就返回0即可。长度为1时,我们只需要返回长度即可。那么,
代码如下:

int removeDuplicates(int* nums, int numsSize){
    
    
    if(numsSize<=1)
    {
    
    
        return numsSize;
    }
    int fast=1,slow=1;
    //fast表示访问的下标,slow表示返回的长度,也表示新数组下一个元素该填的位置
    while(fast<numsSize)
    {
    
    
        //nums[slow-1]表示新数组最后一个元素
        //当它与nums[fast]不同,则nums[slow]需要替换
        if(nums[slow-1]!=nums[fast])
        {
    
    
            nums[slow]=nums[fast];
            slow++;
        }
        fast++;
    }
    return slow;

}

力扣:80

在这里插入图片描述
在这里插入图片描述

思路:这道题与26题相比,会发现改变条件是出现次数超过两次的元素只有两次;我们的思路先保持与上面一致,上面思路是新数组的最后一个元素与当前访问的新元素比较;在这里我们要改变条件是最后一个元素改为倒数第二个元素。

在这里插入图片描述

所以,我们是将nums[slow-2]与nums[fast]进行比较,对于slow-1位置上的元素,在这个例子中,可能性只有是1或者2,如果是1,表明新数组已有两个相同元素,slow位置存的是不相同的;如果是2,表明slow存的是第二个2;综上,slow-1位置不会影响检索条件。上面给出新数组是假设性的,实际题目要求空间复杂度为O(1)。接着对初始化条件修改为新数组有两个元素了,再加上特殊条件即可。

int removeDuplicates(int* nums, int numsSize){
    
    
    //当数组长度小于等于2时直接返回
    if(numsSize<=2)
    {
    
    
        return numsSize;
    }
    int slow=2,fast=2;
    while(fast<numsSize)
    {
    
    
        if(nums[slow-2]!=nums[fast])
        {
    
    
            nums[slow]=nums[fast];
            slow++;
        }
        fast++;
    }
    return slow;
}

猜你喜欢

转载自blog.csdn.net/m0_74068921/article/details/130798973