leetcode 287. 寻找重复数【Medium】【数组】 && 剑指Offer 面试题3 题目2:不修改数组找出重复的数字

       这道题leetcode和剑指Offer题目略有不同。leetcode说数组中的重复数可能不止一个,但是结果要求返回一个就行;剑指Offer上说只有一个重复的数,但是重复的次数不一定。两个题目的共性就是只需要返回一个重复的数即可。

leetcode 题目:

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

示例 1:

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

示例 2:

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

说明:

  1. 不能更改原数组(假设数组是只读的)。
  2. 只能使用额外的 O(1) 的空间。
  3. 时间复杂度小于 O(n2) 。
  4. 数组中只有一个重复的数字,但它可能不止重复出现一次。

思路:

由于不能使用额外的空间,不能使用记录或统计出现的数,又不能破坏数组结构,不能通过排序来判断相邻数是否相等。

       1.暴力法,两层循环,时间复杂度O(n2)太高。

       2.用集合保存遍历值,时间复杂度n,但有额外空间开销。

       3.归并排序,时间复杂度nlogn,空间复杂度 O(1),但破坏数组结果。

       4.二分法,因为数出现在[1,n]。所以统计[1-n/2]的数,如果出现小于等于n/2的数个数超过n/2,[1-n/2]数中有重复的数,继续通过二分减少搜索范围,这里的时间复杂度为nlogn。


代码:

class Solution:
    def findDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        low,high = 1,len(nums)
        while low < high:
            count = 0
            mid = (low + high)//2
            for item in nums:
                if item <= mid:
                    count += 1
            if count > mid:
                high = mid
            else:
                low = mid + 1
        return low

猜你喜欢

转载自blog.csdn.net/weixin_40449071/article/details/83141223