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

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

双指针思想

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


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



相关文章
|
2月前
leetCode(删除有序数组中的重复项)
如何在不使用额外空间的情况下,通过双指针法原地删除有序数组中的重复项。
38 2
|
4月前
|
存储 Java API
LeetCode------合并两个有序数组(4)【数组】
这篇文章介绍了LeetCode上的"合并两个有序数组"问题,并提供了三种解法:第一种是使用Java的Arrays.sort()方法直接对合并后的数组进行排序;第二种是使用辅助数组和双指针技术进行合并;第三种则是从后向前的双指针方法,避免了使用额外的辅助数组。
LeetCode------合并两个有序数组(4)【数组】
|
2月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
24 4
|
2月前
【LeetCode 48】108.将有序数组转换为二叉搜索树
【LeetCode 48】108.将有序数组转换为二叉搜索树
43 0
|
4月前
|
算法
LeetCode第26题删除有序数组中的重复项
这篇文章介绍了LeetCode第26题"删除有序数组中的重复项"的解题方法,通过使用双指针技巧,高效地去除数组中的相邻重复元素。
LeetCode第26题删除有序数组中的重复项
|
4月前
|
算法
LeetCode第80题删除有序数组中的重复项 II
文章介绍了LeetCode第80题"删除有序数组中的重复项 II"的解法,利用双指针技术在O(1)空间复杂度内原地删除重复元素,并总结了双指针技术在处理有序数组问题中的应用。
LeetCode第80题删除有序数组中的重复项 II
|
4月前
|
算法
LeetCode第88题合并两个有序数组
文章分享了LeetCode第88题"合并两个有序数组"的解法,通过从后向前的合并策略避免了数组元素的前移,使用三个指针高效地完成了合并过程。
|
4月前
|
Python
【Leetcode刷题Python】108. 将有序数组转换为二叉搜索树
LeetCode上108号问题"将有序数组转换为二叉搜索树"的Python实现,通过递归选取数组中间值作为根节点,构建高度平衡的二叉搜索树。
31 2
|
4月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
56 0
|
4月前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
48 0