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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值