【Leetcode数据结构算法题】删除有序数组中的重复项(顺序表篇)

题目内容:

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

在这里插入图片描述
Leetcode题目链接(点击即可跳转)


思路分析

我们先假设没有“原地”删除重复项的这个要求,如果我们要解决“删除有序数组中的重复项”,能采取什么样的方法?(开动小脑袋瓜,想一想!)
我们可以先创建一个临时数组,遍历原数组,将数组中的非重复元素放到临时数组中,最后将临时数组的内容拷贝回原数组。
在这里插入图片描述
为了达到“原地”的效果,能不能想办法既不开辟临时数组,又能达到上面的效果呢?
(肯定是有办法的,不然我也不会问你了,给自己挖坑呢不是?)


双指针虚拟数组法

实际上,对于数组而言,指针的功能可以利用下标去实现。这里之所以要说是双指针而不是双下标,是因为这种方法在以后的链表中也会经常使用到,链表里面可不能用下标去解决问题,而需要用指针!!!
再使用这个方法的时候,一定要先考虑原数组的长度,如果长度 <= 1,则不可能有重复项元素,直接返回原数组长度即可。(连两个元素都没有,哪来的重复项?别逗了,咦,别睡着了!)

算法图解:
在这里插入图片描述

函数接口实现

int removeDuplicates(int* nums, int numsSize){
    
    
    //首先判断数组的长度是否小于2
    if(numsSize < 2)
       return numsSize;
    int fast = 1;//fast从下标为1开始,即第二个元素
    int slow = 0;//slow从第一个元素开始,下标为0
    while(fast < numsSize){
    
    
        if(nums[fast] != nums[slow]){
    
    
            //先将slow + 1,然后将fast所在位置的值给slow,然后fast + 1
            nums[++slow] = nums[fast++];//这是简洁的写法
        }
        else{
    
    
            //fast位置值 = slow位置值,直接跳过
            fast++;
        }
    }
    return slow+1;//slow是最后一个元素的下标,则长度为slow+1
}

在这里插入图片描述

总结:
//情况1:数组仅有一个元素,或者0个元素
//情况2:数组里面至少有2个元素
//有序数组,如果后面的元素跟前面的元素相同时,直接跳过这个元素 //不同时,将元素放到虚拟数组中
注意:最后的返回值应该是slow+1,而不是slow

おすすめ

転載: blog.csdn.net/QIYICat/article/details/122247304