今天梳理了一下二分查找及其各类变体,用python写的,代码及运行结果如下
文章目录
排序数组
函数体
查找target
# 查找target
# 找到 —— 返回索引,找不到 —— 返回-1
def Search(array, left, right, target):
while left <= right:
mid = left + int(0.5 * (right - left))
if array[mid] < target:
left = mid + 1
elif array[mid] > target:
right = mid - 1
else:
return mid
return -1
查找第一个等于target的元素
# 查找第一个等于target的元素
# 找到 —— 返回索引,找不到 —— 返回-1
def SearchFirst(array, left, right, target):
while left <= right:
mid = left + int(0.5 * (right - left))
if array[mid] < target:
left = mid + 1
elif array[mid] > target:
right = mid - 1
else:
if mid == left or array[mid-1] != target:
return mid
else:
right = mid - 1
return -1
查找最后一个等于target的元素
# 查找最后一个等于target的元素
# 找到 —— 返回索引,找不到 —— 返回-1
def SearchLast(array, left, right, target):
while left <= right:
mid = left + int(0.5 * (right - left))
if array[mid] < target:
left = mid + 1
elif array[mid] > target:
right = mid - 1
else:
if mid == right or array[mid+1] != target:
return mid
else:
left = mid + 1
return -1
查找第一个大于等于target的元素
# 查找第一个大于等于target的元素
# 找到 —— 返回索引,找不到 —— 返回-1
def SearchFirstLarger(array, left, right, target):
while left <= right:
mid = left + int(0.5 * (right - left))
if array[mid] < target:
left = mid + 1
else:
if mid == left or array[mid-1] < target:
return mid
else:
right = mid - 1
return -1
查找最后一个小于等于target的元素
# 查找最后一个小于等于target的元素
# 找到 —— 返回索引,找不到 —— 返回-1
def SearchLastSmaller(array, left, right, target):
while left <= right:
mid = left + int(0.5 * (right - left))
if array[mid] <= target:
if mid == left or array[mid+1] > target:
return mid
else:
left = mid + 1
else:
right = mid - 1
return -1
函数调用及结果
array = [2,2,3,5,6,7,7,8,9,10,10]
print(Search(array, 0, len(array)-1, 6))
print(SearchFirst(array, 0, len(array)-1, 7))
print(SearchLast(array, 0, len(array)-1, 7))
print(SearchFirstLarger(array, 0, len(array)-1, 4))
print(SearchLastSmaller(array, 0, len(array)-1, 4))
4
5
6
3
2
旋转数组
题目:假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution:
def search(self, nums: List[int], target: int) -> int:
# 二分查找
def search(nums, left, right, target):
while left <= right:
mid = int((left + right)/2)
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
if not nums:
return -1
# 如果是旋转数组,则二分查找出分界点,然后确认target在哪一段,进行二分查找
if nums[0] > nums[-1]:
# 查找分界点
left, right = 0, len(nums) - 1
while left <= right:
mid = int((left + right)/2)
if nums[mid] > nums[left]:
left = mid
elif nums[mid] < nums[right]:
right = mid
else:
partition = mid
break
# 分界点为partition,分段查找
if target >= nums[0]:
return search(nums, 0, partition, target)
else:
return search(nums, partition+1, len(nums)-1, target)
else:
# 未旋转,直接查找
return search(nums, 0, len(nums)-1, target)