二分搜索(常规左边界右边界)
Posted 抚琴尘世客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分搜索(常规左边界右边界)相关的知识,希望对你有一定的参考价值。
1. 概述
二分查找的思想是在有序数组里根据中间值来收缩搜索空间。时间复杂度为O(log(n))。
2. Code实现
2.1 常规
1 # 数组查找是否某个数,存在返回其下标,
2 def binarySearch_any(self, nums, target):
3 if not nums or len(nums) == 0:
4 return -1
5 n = len(nums)
6 # 左右均是闭区间
7 left, right = 0, n - 1
8 # <=: 闭区间[left, right]内查找
9 # 若一直未找到,left = right + 1,写成区间:[right + 1, right]
10 while left <= right:
11 # 方式left + right太大越界
12 mid = left + (right - left) // 2
13 # 找到
14 if nums[mid] == target:
15 # *** 1. 直接返回 ***
16 return mid
17 elif nums[mid] < target:
18 # 注意
19 left = mid + 1
20 elif nums[mid] > target:
21 # 注意
22 right = mid - 1
23 # 未找到
24 # *** 2. 直接返回 ***
25 return left
2.2 左边界
# 返回排序数组中第一次出现的下标,记找左边界
def binarySearch_left(self, nums, target):
if not nums or len(nums) == 0:
return -1
n = len(nums)
# 左右均是闭区间
left, right = 0, n - 1
# <=: 闭区间[left, right]内查找
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
# *** 1. 别返回,收缩右边界,锁定左边界 ***
right = mid - 1
elif nums[mid] < target:
# 搜索区间变为[mid, right]
left = mid + 1
elif nums[mid] > target:
# 搜索区间变为[left, mid - 1]
right = mid - 1
# *** 2. 最后要检查left越界情况 ***
if left >= n or nums[left] != target:
return -1
return left
2.3 右边界
# 返回排序数组中最后一次出现的下标,记找右边界
def binarySearch_right(self, nums, target):
if not nums or len(nums) == 0:
return -1
n = len(nums)
# 左右均是闭区间
left, right = 0, n - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
# *** 1. 别返回,收缩左边界,锁定右边界 ***
left = mid + 1
elif nums[mid] < target:
# 搜索区间变为[mid + 1, right]
left = mid + 1
elif nums[mid] > target:
# 搜索区间变为[left, mid - 1]
right = mid - 1
# *** 2. 最后要检查right越界情况 ***
if right < 0 or nums[right] != target:
return -1
return right
3. 结语
努力去爱周围的每一个人,付出,不一定有收获,但是不付出就一定没有收获! 给街头卖艺的人零钱,不和深夜还在摆摊的小贩讨价还价。愿我的博客对你有所帮助(*^▽^*)(*^▽^*)!
如果客官喜欢小生的园子,记得关注小生哟,小生会持续更新(#^.^#)(#^.^#)。
但行好事 莫问前程
以上是关于二分搜索(常规左边界右边界)的主要内容,如果未能解决你的问题,请参考以下文章
hdu1540-Tunnel Warfare-(线段树+二分)
贪心算法第五篇: 区间问题(右边界总是大于左边界-隐含条件)