删除排序数组中的重复项

删除排序数组中的重复项 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

  1. 最初思路,使用for循环
 l = len(nums)
    j=1
    for i in range(0, l):
        if i == 0:
            continue
            j=j+1
        else:
            if nums[i] in nums[:i]:
                del nums[i]
    return len(nums)

出现的错误:
在这里插入图片描述
分析原因:使用循环的思想逐个判断元素并删除的思路是正确的,但在del之后,num的长度变小了,此时l不变,所以索引超出范围。
解决方法:再使用一个新的变量j,来控制nums的索引。

l = len(nums)
    j=1
    for i in range(0, l):
        if i == 0:
            continue
            j=j+1
        else:
            if nums[j] in nums[:j+1]:
                del nums[j]
            else:
                j=j+1
    print(nums)

结果: [1,1,2]变成了[1].
分析原因:

 if nums[j] in nums[:j+1]:

改为

 if nums[j] in nums[:j]:

将第n个待检查的与前n-1个相比较。运行结果通过。

  1. 尝试使用while循环
def removeDuplicates2(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    j=1
    while(j<len(nums)):
        if nums[j] in nums[:j]:
            del nums[j]
        else:
                j=j+1
    print(nums)
    return

运行结果通过。
使用while循环,可以只用一个变量控制,不用像for循环一样,一个控制nums长度,一个控制原本的元素个数。

  1. 官方推荐——双指针

首先注意数组是有序的,那么重复的元素一定会相邻。 要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。

考虑用 2 个指针,一个在前记作 p,一个在后记作 q,算法流程如下:

1.比较 p 和 q 位置的元素是否相等。

如果相等,q 后移 1 位 如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位 重复上述过程,直到 q
等于数组长度。

返回 p + 1,即为新数组长度。

首先注意数组是有序的,那么重复的元素一定会相邻。
要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。
考虑用 2 个指针,一个在前记作 p,一个在后记作 q,算法流程如下:
1.比较 p 和 q 位置的元素是否相等。如果相等,q 后移 1 位
如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位
2.重复上述过程,直到 q 等于数组长度。返回 p + 1,即为新数组长度。

    p=0
    q=1
    while(q<len(nums)):
        if (nums[p]!= nums[q]):
            nums[p+1]=nums[q]
            p=p+1
        q=q+1
    print(nums)

优化:
在这里插入图片描述

    p=0
    q=1
    while(q<len(nums)):
        if (nums[p]!= nums[q]):
            if q-p >1:
                nums[p+1]=nums[q]
            p=p+1
        q=q+1
    print(nums)
  1. C++语言
    学过的全忘光了,捡起来C++再说吧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值