【每日一题】【LeetCode】【第二十六天】【Python】存在重复元素 II

解决之路= =

题目描述

在这里插入图片描述

测试案例(部分)

**加粗样式**

第一次

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        index = 0
        n = len(nums)
        while index < n - k:
            for i in range(1, k + 1):
                if nums[index] == nums[index + i]:
                    return True
            index += k
        return False

k>=n的情况下会报错。
在这里插入图片描述

第二次

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        index = 0
        n = len(nums)
        if k >= n:
            if len(nums) != len(list(set(nums))):
                return True
            else:
                return False
        while index < n - k:
            for i in range(1, k + 1):
                if nums[index] == nums[index + i]:
                    return True
            index += k
        return False

k还存在为0的情况
在这里插入图片描述

第三次

再加个判断,k=0时(同样位置的元素按题目意思不算满足条件),肯定返回的是False。

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        index = 0
        n = len(nums)
        if k == 0:
            return False
        if k >= n:
            if len(nums) != len(list(set(nums))):
                return True
            else:
                return False
        while index < n - k:
            for i in range(1, k + 1):
                if nums[index] == nums[index + i]:
                    return True
            index += k
        return False

又错了,盘一下代码逻辑,看看是哪里错了。
在这里插入图片描述

改了几版,还是不对

在这里插入图片描述
开始想着重新换个思路实现了。

第三次

想来想去,想到了滑动窗口的思路,但之前写代码都没写过这种,只是在计算机网络的学习中遇到这名字,好像是通信的一种传递信息的算法,可以形象的比喻成滑动的一个区间,也称为滑动窗口。

class Solution(object):
    def isRepeat(self, num_list):
        """ 判断数组是否有重复元素 """
        if len(num_list) == len(list(set(num_list))):
            return False
        else:
            return True
    def containsNearbyDuplicate(self, nums, k):
        # 窗口区间的两端
        left, right = 0, k
        n = len(nums)
        # 窗口长度为 0
        if k == 0:
            return False
        # 窗口长度大于等于数组长度,就等于没有窗口了
        if k >= n:
            return self.isRepeat(nums)
        while right < n:
            if self.isRepeat(nums[left: right + 1]):
                return True
            else:
                left += 1
                right += 1
        return False

测试是正确的,提交!

**加粗样式**

超时了,看来滑动窗口虽然可以解决问题,但是耗费时间还是需要优化。

**加粗样式**

第四次

改一下逻辑,不用频繁的切片操作看看能不能少点时间。

class Solution(object):
    def isRepeat(self, num_list):
        """判断数组是否有重复元素"""
        if len(num_list) == len(list(set(num_list))):
            return False
        else:
            return True
    def containsNearbyDuplicate(self, nums, k):
        queue = []
        for i in nums:
            if len(queue) > k:
                queue.pop(0)        # 去头
                queue.append(i)     # 加尾
            else:
                queue.append(i)     # 直接加尾
            if self.isRepeat(queue):
                return True
        return False

还是不行。

在这里插入图片描述

第五次

看了看评论区,讲到的思路和自己的也很像啊。

在这里插入图片描述

自己也是每轮保持长度的同时,加入新的元素,不断判断集合是否有重复元素。

再看看别人写的题解,有一个方法就是这个思路写的滑动窗口。

在这里插入图片描述
直接用in来判断是否重复就可以了,不过这样写的话,用不用集合好像都可以?自己试着改改自己的代码。

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        queue = []
        for i in nums:
            if len(queue) > k:
                queue.pop(0)    # 去头
            if i in queue:
                return True
            queue.append(i)
        return False

测试正确,提交成功。
在这里插入图片描述

就是耗时很长,换成集合再来看看时间差别。

在这里插入图片描述

这么看来,集合的操作效率比列表高?不确定,在CSDN论坛问问大佬,后续更新出来

第六次(用字典)

第一次看到用到python字典的题,应该是利用了字典的存取速度大大降低了耗时,可以学一下。

# 来源:https://leetcode.cn/problems/contains-duplicate-ii/solution/python3-ha-xi-biao-by-ting-ting-28/
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        dct = {}
        for i in range(len(nums)):
            if nums[i] in dct and dct[nums[i]] >= i-k:
                return True
            dct[nums[i]] = i
        return False

杂谈

后续安排改一下,毕竟不是过年放假期间有那么多时间了,尤其是第一周= =。

第一周(2.6–2.12)请个假,暂缓更新。

每周6天更新每日一题,周一到周五每天正常写一个简单题,周六周日两天写一个中等题。

附件中每天背单词的截图也不天天上传了,每周在中等题那一篇每日一题中放上一周背单词打卡截图。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值