算法练习第52题-寻找重复数

144 阅读2分钟

一、题目

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。  

示例 1:

输入:nums = [1,3,4,2,2]
输出:2
示例 2:

输入:nums = [3,1,3,4,2]
输出:3

作者:力扣 (LeetCode) 链接:leetcode.cn/leetbook/re… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二、思考

暴力解法

  • collections.Counter() 提供计数器工具以支持方便和快速的计数
  • 如果存在重复的整数,就通过for循环加1
  • 因此就得到了一个技术的字典,通过循环这个字典,value大于1的值就是要的参数
  • 这里使用推导式得出结果

二分查找

  • 首先定义左右区间,leftIndex, rightIndex,中间值mid, 最终结果ans
  • 通过循环,判断中间值的与大于中间值的数量
  • 如果大于中间值,说明当前区间应该向左移动
  • 如果小于中间值,那么说明右区间应该向左移动,同时得到的中间值就是返回值

三、代码

暴力解法

nums = [1,3,4,2,2]
class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        """
        collections.Counter() 提供计数器工具以支持方便和快速的计数
        如果存在重复的整数,就通过for循环加1
        因此就得到了一个技术的字典,通过循环这个字典,value大于1的值就是要的参数
        这里使用推导式得出结果
        :param nums:
        :return:
        """
        m = collections.Counter()
        for num in nums:
            m[num] += 1
        return [k for k, v in m.items() if v > 1][0]


Solution().findDuplicate(nums)

二分查找

nums = [3,1,3,4,2]
class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        """
        二分查找
        首先定义左右区间,leftIndex, rightIndex,中间值mid, 最终结果ans
        通过循环,判断中间值的与大于中间值的数量
        如果大于中间值,说明当前区间应该向左移动
        如果小于中间值,那么说明右区间应该向左移动,同时得到的中间值就是返回值
        处理
        :param nums:
        :return:
        """
        len1, leftIndex, rightIndex, ans = len(nums), 1, len(nums) - 1, -1
        while leftIndex <= rightIndex:
            mid = (leftIndex + rightIndex) // 2
            cnt = 0
            for i in nums:
                cnt += i <= mid
            if cnt <= mid:
                leftIndex = mid + 1
            else:
                rightIndex = mid - 1
                ans = mid
        print(ans)
        return ans




Solution().findDuplicate(nums)

四、测试结果

暴力解法

image.png

二分查找

image.png