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

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

双指针思想

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


力扣: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;
}



相关文章
|
5天前
|
算法
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
|
5天前
|
存储
【合并两个有序数组】LeetCode第88题讲解
【合并两个有序数组】LeetCode第88题讲解
|
5天前
leetcode代码记录(删除字符串中的所有相邻重复项
leetcode代码记录(删除字符串中的所有相邻重复项
12 0
|
5天前
leetcode代码记录(有序数组的平方
leetcode代码记录(有序数组的平方
8 0
|
5天前
leetcode代码记录(有序数组两数之和
leetcode代码记录(有序数组两数之和
13 0
|
5天前
【力扣】80.删除有序数组中的重复项Ⅱ
【力扣】80.删除有序数组中的重复项Ⅱ
|
5天前
|
存储
【力扣经典面试题】80. 删除有序数组中的重复项 II
【力扣经典面试题】80. 删除有序数组中的重复项 II
|
5天前
|
存储
【力扣经典面试题】合并两个有序数组
【力扣经典面试题】合并两个有序数组
|
5天前
|
存储 C语言
【C语言】Leetcode 88.合并两个有序数组
【C语言】Leetcode 88.合并两个有序数组
17 3
|
5天前
LeetCode刷题---80. 删除有序数组中的重复项 II(双指针)
LeetCode刷题---80. 删除有序数组中的重复项 II(双指针)