文章目录
一:按下标搜索和按值搜索
对于任何二分查找的题目最重要的是弄清楚搜索空间,我认为,搜索空间分为两种:
- 一个是按数组的下标搜索 ----> (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 []