【LeetCode】961. 在长度 2N 的数组中找出重复 N 次的元素

112 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

  • 题目示例

  • 题目解析

    • 2 <= n <= 5000
    • nums.length == 2 * n
    • 0 <= nums[i] <= 104
    • nums 由 n + 1 个 不同的 元素组成,且其中一个元素恰好重复 n 次

二、思路分析:

根据题目,要求找出nums列表中重复次数在n次的元素,作为菜鸟的我本题会做。

方法一:count()方法:

  • 使用for循环,遍历nums列表
  • 借助python list.count()方法,对每一个元素出现次数进行判断等于 len(nums)/2 次

根据上述思路,二话不说就实现了如下代码:

class Solution(object):

    def repeatedNTimes(self, nums):

        n = len(nums)/2

        for num in nums:

            if nums.count(num) == n:

                return num

提交运行,102个用例都能过,心里OS:“就这,不会太简单了吧”,不使用count()方,还有其他方法可以实现吗?

仔细审题意,题目中:nums中元素包含 n+1个元素

  • 列表 nums 的长度为2n
  • 其他元素都只能出现一次

方法二:哈希表方法

  • 引入一个字典tmp,存储 nums 列表中的元素
  • 当遍历nums中,只要遍历的元素num存在字典中,则返回结果
class Solution(object):

    def repeatedNTimes(self, nums):

        tmp = {}

        for num in nums:

            if num in tmp.keys():               

                return num          

            tmp[num]= True        

        return -1      

提交AC,时间明显比方法一快了,打败80%的用户,但是时间复杂度O(n),空间复杂度O(n)

方法三:数学方法

题目要求nums的长度为2n,并且不同的元素为n+1,那么我们可以求出重复的元素为 n-1个

  • 当 n = 2时,重复元素间隔次数有三个情况:0,1,2

image.png

  • 当 n > 2时,重复元素间隔次数最到不超过2个元素,否则就不满足题目要求

image.png

因此,我们找到数学规律,重复元素之间的间隔不超过个2个,因此下标的范围为1~3

  • 可以使用滑动窗口的思想,定一个step范围在(1,4)
  • 第一层for循环遍历整个nums,i的范围在len(nums)-1,取出nums[i]
  • 第二层for循环在j长度为4的范围内比较nums[i]==nums[i+j]是否有一样的

image.png

根据上述思路,我们可以使用python快速实现出来:

class Solution(object):

    def repeatedNTimes(self, nums):

        """

        :type nums: List[int]

        :rtype: int

        """

        for i in range(len(nums)-1):

            for j in range(1,4):

                if nums[i]==nums[min(i+j,len(nums)-1)]:

                    return nums[i]

        return -1

方法四:随机选择

因为在nums列表中,除了重复的元素外,其余的元素都出现一次。

因此,我们可以在nums列表中,随机选择两个索引 x 和 y

  • 当 x 和 y不相等,并且nums[x] == nums[y]时,我们找出了重复元素
class Solution(object):

    def repeatedNTimes(self, nums):

        n = len(nums)

        while True:

            x,y=  random.randrange(n), random.randrange(n)

            if x != y and nums[x] == nums[y]:

                return nums[x]

方法五:类似摩尔投票算法

  • 摩尔投票算法:用来求数量大于总数量一半的众数
class Solution(object):

    def repeatedNTimes(self, nums): 

        start = nums[0]

        cmd = nums[0]

        for i in range(1,len(nums)):

            if nums[i]== start:

                return start

            if nums[i] == cmd:

                return cmd

            cmd = nums[i]

        return cmd

三、总结:

本题考察我们对于规律列表中找出重复元素,可以根据题目要求情况找出对应的规律来进行求解.如我们使用方法三,AC代码记录如下:

  • 时间复杂度为O(n),对列表要进行最多三次当遍历
  • 空间复杂度为O(1),无额外的空间

以上是本期内容,欢迎大佬们点赞评论,下期见~~