python每日一题 删除有序数组中的重复项

不好意思大家 最近有点懒散  我现在才开始写今天的第一个帖子 

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

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

那意思就是不能创建一个新数组 我们来分析一下 数组已经是有序的了 如果这个元素超过三次的话 那就不行 就删掉多余的 那我觉得可以用两个指针来操作 而且对于删除的话我更倾向于从后面开始删除 那么就开始分情况

指针指向 如果相等往前移动 直到不相等 看差距 差距小于等于2 就不用管 left=right right往后移动 如果是差距大于2了 那就删除 删除之后还是Left=right 然后right往后移

如果觉得自己不明白这个移动和如何删除的 最好还是在纸上画画

class Solution(object):
    def removeDuplicates(self, nums):
        if len(nums)<=2:
            return nums
        left=len(nums)-1#倒数第一个元素
        right =len(nums)-2#倒数第二个元素
        while right>=0:
            if nums[right]==nums[left]:
                right-=1
            else:#如果不等于
                if left-right>=2:
                    del  nums[right+3:left+1]  # 删掉这些
                left=right
                right-=1
        return nums
                #不管是删还是没删 left right的位置都要开始发生改变

solution=Solution()
result=solution.removeDuplicates([1,1,1,2,2,3])
print(result)

这是我写的第一个代码 很遗憾 没有实现功能 我自己验证一下当是1 1 1的时候 right到了-1 直接跑到最后面去了 但是移到索引为0的时候此时还是nums[right]==nums[left] 接下来到-1直接没办法进去while循环了 所以这种操作在遇到开始的几个数是相同的话是不行的 

那么我们就直接来干脆的 移动的时候判断 如果是相等 并且此时差距已经大于等于2 那直接就开删 不用等到不相等的时候了 不然遇到111永远等不到相等的时候了 然后我解释一下下面的代码 当两者相等的时候right就会往前移动 一旦差距大于等于2 就开始删 删完之后更新left的位置 只要二者相等 right就会往前移动 删完之后更新left的位置 right也还是回往前移动 如果不相等更好办了 直接往前移动就可以了

class Solution(object):
    def removeDuplicates(self, nums):
        if len(nums)<=2:
            return nums
        left=len(nums)-1#倒数第一个元素
        right =len(nums)-2#倒数第二个元素
        while right>=0:
            if nums[right]==nums[left]:
                if left-right>=2:
                    del nums[right+2:left+1]#只保留两个
                    left=right+1
                right-=1#
            else:#重复不超过2
                   left=right
                   right-=1
        return len(nums)
                #不管是删还是没删 left right的位置都要开始发生改变
solution=Solution()
nums=[0,0,1,1,1,1,2,3,3]
result=solution.removeDuplicates(nums)
print(nums[:len(nums)])

我这个在pycharm中是没有任何问题的 但是不知道为啥没办法通过测试 那我们一起看大佬的代码是咋写的(嗷嗷我知道了 那个len(nums)<=2 我返回了nums 真该死

class Solution(object):
    def removeDuplicates(self, nums):
        if len(nums) <= 2:
            return len(nums)
        slow = 2  # 慢指针从第3个位置开始
        for fast in range(2, len(nums)):  # 快指针遍历后续元素
            # 比较当前元素与慢指针前两位(控制最多两次重复)
            if nums[fast] != nums[slow-2]:
                nums[slow] = nums[fast]
                slow += 1
        return slow

这个是大佬的代码 我们一起来分析一下 相比于大佬的 我的代码根本没体会到双指针的奥妙  我觉得这个代码单看时很难理解的 我建议还是在纸上写写 就会觉得很神奇了 我描述也很难描述 就是我自己根本想不出来这个代码 只是看这个代码我也看不懂 挖个坑吧 或者大家有没有更好的看懂这个代码的方法 欢迎评论区留言!

请大家多多点赞收藏 你们的鼓励是我更新的最大动力

(今天好好准备的东西 还没别人随便准备的得到的结果好 感觉很多小比赛就是一个很随意的过程 过程闹哄哄的 很随意就决定结果 所以心情也是很down了)晚上才开始真正投入到学习当中  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值