二分查找--按值搜索和按下标搜索总结

一:按下标搜索和按值搜索

对于任何二分查找的题目最重要的是弄清楚搜索空间,我认为,搜索空间分为两种:

  • 一个是按数组的下标搜索 ----> (low = 0, high = len(nums)-1)
  • 另外一个是按数值的范围进行搜索 ----> ( low = min(nums), high =max(nums) )

大多数情况下,当数组是有序或部分有序时是按照数组的下标进行搜索,当数组是无序的时候,就是按照数值的范围进行搜索。

二:leetcode 153. Find Minimum in Rotated Sorted Array

思路:数组部分有序,搜索空间为数组的下标
python实现:

class Solution(object):
    def findMin(self, nums):
        low, high = 0, len(nums)-1
        if nums[low] <= nums[high]: return nums[low]  # len(nums)==1  or 全部有序
        
        while low < high:
            mid = low + (high-low)//2
            if nums[mid] < nums[mid-1] and nums[mid] < nums[mid+1]: return nums[mid] 
            if nums[mid] > nums[mid-1] and nums[mid] > nums[mid+1]: return nums[mid+1] 
            
            if nums[mid] > nums[0]: # pivot在右边
                low = mid + 1
            else:
                high = mid

三:LeetCode 287. Find the Duplicate Number

搜索空间为数值的范围
python实现:

class Solution(object):
    def findDuplicate(self, nums):
    	low, high = 1, len(nums) # 这是数字的范围,不是数组下标
        
        def check(nums, mid): # 统计nums中小于等于数字mid的个数
            ans = 0
            for i in range(len(nums)):
                if nums[i] <= mid:
                    ans += 1
            return ans
    
        while low < high:
            mid = low + (high - low)//2
            if check(nums, mid) > mid: 
                high = mid
            else: 
                low = mid + 1
        
        return low

四:LeetCode 378. Kth Smallest Element in a Sorted Matrix

搜索空间为数值的范围
python实现:

class Solution(object):
    def kthSmallest(self, matrix, k):
        if not len(matrix) or not len(matrix[0]): return 0
		low, high = matrix[0][0], matrix[-1][-1] # 最小值与最大值
        
        def check(nums, mid): # 统计数组中比mid小的数字的个数啊!
            count = 0
            j = len(matrix[0])-1 
            for i in range(len(matrix)):
                while j >= 0 and matrix[i][j] > mid: j -= 1 # 从右往左找,直接去掉了一列的值
                count += (j+1)
            
            return count
        
        while low < high:
            mid = low + (high-low)//2
            if check(matrix, mid) < k: # 1-mid之间的数字的个数比k小
                low = mid + 1
            else:
                high = mid
        return low

五:LeetCode 5276. Number of Burgers with No Waste of Ingredients

1:题意:

我们有土豆片和奶酪片,通过这两种材料制作汉堡,汉堡的种类有两种,分别是大汉堡和小汉堡
大汉堡:4个土豆片+1个奶酪片
小汉堡:2个土豆片+1个奶酪片
现在给你tomatoSlices个土豆片和cheeseSlices个奶酪片,请问你可以分别制作大汉堡和小汉堡多少个?
如果无法组合,则输出[ ] 数组

限制条件:
0 <= tomatoSlices <= 10^7
0 <= cheeseSlices <= 10^7

2:思路

刚开始我没看到限制条件,直接用for循环对奶酪片从0到cheeseSlices进行遍历,判断是否能组合出大汉堡和小汉堡,最后不剩下任何土豆片和奶酪片,然后一提交就超时了,然后我再读题目看到了数据量的大小,我立马意识到这是道二分查找的题。

python实现:

class Solution(object):
    def numOfBurgers(self, tomatoSlices, cheeseSlices):
        if tomatoSlices == 0 and cheeseSlices == 0: return [0,0]
        if tomatoSlices == 0 or cheeseSlices == 0: return []
        if cheeseSlices * 4 < tomatoSlices : return []  # cheeseSlices太少
        
        low, high = 0, cheeseSlices
        while low < high:
            mid = low + (high - low) // 2 # cheeseJumbo的数量
            if mid * 4 + (cheeseSlices - mid) * 2 == tomatoSlices:
                return [mid, cheeseSlices - mid]
            elif mid * 4 + (cheeseSlices - mid) * 2 < tomatoSlices:
                low = mid + 1
            else:
                high = mid
          
        return []
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值