删除排序数组中的重复数字

本文介绍了一种在不使用额外空间的情况下从已排序数组中删除重复元素的方法。通过一个Python实现的例子,展示了如何保持每个元素只出现一次,并返回新数组的有效长度。

给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度。

不要使用额外的数组空间,必须在原地没有额外空间的条件下完成。

样例



给出数组A =[1,1,2],你的函数应该返回长度2,此时A=[1,2]

最开始的想法是遍历数组元素然后用python中的remove函数去除相同元素,但最后结果正确但超时了,
所以改进为将多于的元素放到数组末端

最后一并删除这样比较节省时间
class Solution:
    """
    @param: nums: An ineger array
    @return: An integer
    """
    def removeDuplicates(self, nums):
        j = 0
        for i in range(1,len(nums)):
            if nums[j] != nums[i]:
                j += 1
                nums[j] = nums[i]
        del nums[j + 1: len(nums)]
        return len(nums)
    





<think>好的,用户想了解如何使用双指针法删除数组中的重复数字。首先,我得回忆一下双指针法的基本思想。双指针法通常在数组或链表操作中用于减少时间复杂度,特别是处理元素覆盖或顺序调整的问题。 那删除重复元素的话,通常要求原地修改,也就是不使用额外的空间或者使用O(1)的空间。比如LeetCode上的经典题目“删除有序数组中的重复项”。这时候双指针法应该是适用的。 接下来,我需要确定双指针的具体用法。一般来说,会有一个快指针和一个慢指针。快指针用于遍历整个数组,而慢指针则指向下一个非重复元素应该存放的位置。这样,每当快指针发现一个不重复的元素时,就将其复制到慢指针的位置,然后慢指针前进一步。 比如,对于数组[1,1,2],快指针开始于索引1,慢指针在索引0。当快指针发现元素与慢指针不同时,就将该元素复制到慢指针的下一个位置,然后慢指针移动。这样,最后慢指针的位置+1就是新数组的长度。 不过,用户的问题中没有明确数组是否有序。如果是无序数组,可能需要先排序,但这样会改变原数组的顺序。如果题目要求保持原顺序,但删除重复项,可能需要另一种方法。但通常情况下,双指针法用于有序数组的情况,因为无序的话重复项可能出现在任何地方,处理起来复杂度更高。所以假设用户的问题中的数组是有序的,这样双指针法更有效。 然后,我需要考虑具体步骤。首先判断数组是否为空,如果是的话直接返回0。然后初始化慢指针在0的位置,快指针从1开始遍历。当快指针的元素不等于慢指针的元素时,慢指针先加一,然后赋值,快指针继续。最后返回慢指针+1作为新长度。 同时,需要注意边界条件,比如数组长度为0或1的情况,这时候不需要处理。 然后,用户可能需要一个例子来理解这个过程。例如,数组[0,0,1,1,1,2,2,3,3,4],应用双指针法后,慢指针最后会停在索引4的位置,对应的元素是4,所以新数组长度是5,数组前五个元素是0,1,2,3,4。 另外,要确保代码实现正确。比如在Python中,数组可以通过指针操作覆盖元素,最终返回长度即可。需要注意在赋值时的顺序,先移动慢指针再赋值,避免覆盖错误。 可能用户还会有疑问,比如为什么可以这样做?因为数组是有序的,重复的元素必然是连续的,所以只要比较快指针和慢指针的元素是否相同,就可以确定是否需要保留当前元素。 总结下来,步骤是:初始化两个指针,快指针遍历,慢指针记录非重复位置,每次发现不同元素就移动慢指针并赋值,最后返回长度。这样时间复杂度是O(n),空间是O(1)。</think>### 双指针法删除数组重复数字分步详解 #### 一、适用条件 1. **有序数组**(若数组无序需先排序,但会改变原始顺序) 2. **原地修改**(空间复杂度 $O(1)$) #### 二、算法原理 - **快指针**:遍历数组,寻找新元素 - **慢指针**:标记唯一元素应插入的位置 #### 三、具体步骤(以数组 `[0,0,1,1,1,2,2,3,3,4]` 为例) 1. **初始化指针** - 慢指针 `slow = 0` - 快指针 `fast = 1` - 初始状态:`[0,0,1,1,1,2,2,3,3,4]` ↑ ↑ slow fast 2. **遍历过程** - `fast=1`:`nums[fast] = nums[slow]`,跳过 - `fast=2`:`nums[fast] ≠ nums[slow]` - `slow += 1` → `slow=1` - `nums[slow] = nums[fast]` → `[0,1,1,1,1,2,2,3,3,4]` ↑ ↑ slow fast 3. **继续遍历** - `fast=3~4`:重复值,跳过 - `fast=5`:`nums[fast]=2 ≠ nums[slow]=1` - `slow +=1` → `slow=2` - 赋值 → `[0,1,2,1,1,2,2,3,3,4]` ↑ ↑ slow fast 4. **最终结果** - 遍历完成后,`slow=4`,返回长度 `slow+1=5` - 新数组前5位:`[0,1,2,3,4]` #### 四、代码实现(Python) ```python def removeDuplicates(nums): if not nums: return 0 slow = 0 for fast in range(1, len(nums)): if nums[fast] != nums[slow]: slow += 1 nums[slow] = nums[fast] return slow + 1 ``` #### 五、复杂度分析 1. **时间复杂度**:$O(n)$,仅遍历一次数组 2. **空间复杂度**:$O(1)$,仅使用常量空间 #### 六、关键点总结 - **有序性保障**:确保重复元素连续 - **指针移动条件**:仅当快指针发现新唯一值时移动慢指针 - **覆盖策略**:直接修改原数组前部内容,避免额外空间 #### 七、扩展思考 若数组无序且要求保持原始顺序,可通过哈希表记录已出现元素(空间复杂度 $O(n)$),或先排序再使用双指针法(时间复杂度 $O(n \log n)$)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值