基于Python3数组
二分法查找的思路很简单,先肯定好列表nums的一头start一尾end,中间值middle根据头尾数值之和用地板除法除以2,即(start + end) // 2。将目标值target与nums[middle]进行比对,这时候有3种结果:code
以上3种状况前2种不断循环,直到知足第3种跳出循环。排序
说明target在前半段,因此end=middle-1get
说明target在后半段,因此start=middle+1List
说明target就是nums[middle],因此返回middle,这是跳出循环的方式之一
因此到此能够写出循环体中的代码,以下:循环
middle = (start + end) // 2 if target > nums[middle]: start = middle + 1 elif target < nums[middle]: end = middle - 1 else: return middle
可是,万一一直达不到第3种的条件呢?即target压根不在列表nums中,这就出现了状况4时间
咱们循环到最后阶段必定是start=middle-1=end-2,即start与middle与end紧挨着。这时候,咱们将start,middle,end代入if语句进行分析,while
那么此时还有最后一个值须要判断,以上2种状况再代入循环体,此时有start=end=middle。若没有nums[middle]=target,则跳出循环(此为跳出循环的方式之二)返回-1
很明显,start与end一直互相逼近,可是start一直小于end的,要不要加上等于这个条件呢?别忘了只有start=end,才可以对列表中的最后一个元素进行判断。co
完整代码以下:block
def binarySearch(nums, target): start = 0 end = len(nums) -1 while start <= end: middle = (start + end) // 2 if target > nums[middle]: start = middle + 1 elif target < nums[middle]: end = middle - 1 else: return middle return -1 if __name__ == "__main__": List = [1,4,4,5,7,7,8,9,9,10] print(List) print(binarySearch(List, 1)) # output # [1, 4, 4, 5, 7, 7, 8, 9, 9, 10] # 0
给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),若是target不存在于数组中,返回-1。
普通的二分查找只要找到target就好了,这个必须考虑到列表中重复的元素。
也就是说,即使找到了也不能跳出循环体。那么怎样才能跳出循环体呢?
别忘了跳出循环的方式有2种,刚才只是封住了第1种,还有第2种呢。即while的设置条件。很明显,start小于end是必须的循环条件的,而start大于end确定是跳出循环的条件,那么start=end是跳出仍是不跳出呢?首先要清楚start=end的意义是什么,即通过迭代此时列表nums中的选择区域变成了一个元素,循环的做用是将这最后一个元素选出来。
跳出循环,去判断是哪一种可能。这个元素只有2种可能:不知足target或者是知足target的第一个元素。
注意,和普通二分法状况同样,循环到最后阶段必定是start=middle-1=end-2,即start与middle与end紧挨着。这时候,咱们将start,middle,end代入if语句进行分析,
如何肯定是知足target的第一个元素?
先明白循环中找到第一个等于target的nums[middle]元素不跳出循环应该作什么。很明显,应该搜寻nums[start:middle]区域,因此要赋值end=middle,即搜寻新的nums[start:end]区域。再次循环,此时只剩下2种结果,再找到等于target的nums[middle] 或者 找不到了
以上2种结果互相交错,循环到最后阶段必定是start=middle-1=end-2,即start与middle与end紧挨着。这时候,咱们将start,middle,end代入if语句进行分析,
def binarySearch(nums, target): start = 0 end = len(nums) -1 while start < end: middle = (start + end) // 2 if target > nums[middle]: start = middle + 1 elif target < nums[middle]: end = middle - 1 else: end = middle if nums[start] == target: return start return -1 if __name__ == "__main__": List = [1,4,4,5,7,7,8,9,9,10] print(List) print(binarySearch(List, 4)) # output # [1, 4, 4, 5, 7, 7, 8, 9, 9, 10] # 1