剑指offer秋招准备(python版)---面试题3 ---附加 二分查找

题目:在一个长度为n+1的数组中,元素的大小在1~n之间(都是整数),说明一定存在重复数字,试问能不能在不修改数组的情况下找到一个重复的数字。实例【2,3,5,4,3,2,6,7】共8个数,在1到7的范围内,取中间的数字4,1~4之间包括1/2/3/4,在数组中,在这个范围内的数为5个,超过了该范围应该有的个数,故重复数字出现在1~4区间,之后继续这个过程,直至范围内数字个数等于2.

二分查找理念:一定有一个数出现了两次,将数组的范围一分为二,如果说没有重复的数字情况下,每个范围内数字个数都应该等于该范围的大小,如果超过了该范围,即是重复的数字出现在该范围。原因:一定有重复数字,而且,如果范围内有缺失数字的话,重复数字还不止一个。

该算法的时间复杂度o(nlogn),空间O(1),拿时间换空间,还可以用空间换时间,比如之前采用的重排数组、字典法

可以根据面试官的要求(找到一个、所有)、或者性能要求(时间效率优先、空间效率优先)选取不同的算法

class Solution:
    def findSameNum(self,A):
        if len(A)<2:
            return False
        for i in range(len(A)):
            if A[i]<1 or A[i]>=len(A):
                return False
        left=1
        right=len(A)-1
        while left<right:
            mid=(right-left)//2+1#尽量分布均匀
            leftFre=self.findFre(A,left,mid)
            if leftFre>mid-left+1:
                right=mid
            else:
                left=mid+1

        print(left)
        return left#总的时间复杂度nlogn,注意返回的是left,而非A

    def findFre(self,A,left,right):#时间复杂度n
        fre=0
        for item in A:
            if item>=left and item<=right:
                fre+=1
        return fre

example=Solution()
example.findSameNum([2,3,5,4,3,2,6,7])

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值