二分法针对的是有序数组!
leetcode二分法的题目:链接
普通二分法查找目标值的index
二分法的思路很简单,先确定好列表nums一头start和一尾end,中间值middle根据头尾数值之和除以2,即(start+end)//2,将目标值与nums[middle]进行比对,这时有三种情况:
1)nums[middle] > target 说明target在前半段,end=middle-1
2)nums[middle] < target 说明target在后半段,start=middle+1
3)nums[middle] = target 说明target就是nums[middle],所以返回middle,跳出循环
前两种情况不断循环,直到满足第三种跳出循环。
但是如果一直都达不到第三种的条件呢?即target压根不在列表nums中。比如列表中的元素是1 3 5 7,而target是9,查找到最后start是2,end是3,如果用start<end的条件,middle就是2,永远也查不到7这个数,就退出循环了。所以,为了判断列表中最后一个元素,判断条件必须是start<=end!
如果不存在,比如12没有,最终end是9, start是10;比如0没有,最终start是0, end是-1!所有最终二分法的start和end都回归到这种结果!!!!
如果找一个数,没有找到,start指向的就是他应该在的索引位置,而end是start-1。
比如找6,6就应该在第一个7出现的位置,所以start是4,end是3!
def binarySearch(nums, target):
start = 0
end = len(nums) -1
while start <= end:
middle = (start + end) // 2
if target == nums[middle]:
return middle
elif target > nums[middle]:
start = middle + 1
else:
end = middle - 1
return -1
if __name__ == "__main__":
List = [1,4,4,5,7,7,8,9,9,10]
print(List)
print(binarySearch(List, 1))
给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。
lintcode:链接
这里的要求和一般的二分查找还不太一样,主要的原因是题目要求查找出第一个,也就是即使找到了一个,也不能立即返回,需要找到第一个才行。
!!!!比如12没有找到,这时的start是10,end是9,所以一定要判断start是不是在索引之内!!
def binarySearch(nums, target):
start = 0
end = len(nums) -1
while start <= end:
middle = (start + end) // 2
if target > nums[middle]:
start = middle + 1
else:
end = middle - 1
if start <= len(nums)-1 and nums[start] == target:
return start
return -1
if __name__ == "__main__":
List = [1,4,4,5,7,7,8,9,9,10]
print(binarySearch(List, 7))