基於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