進行二分查找課程回顧與總結,包括如下幾個方面,二分法的模板總結和解題思路、應用。python
二分法模板總結classical binary search:算法
1. 必需要作的排除極端狀況,也就是數組(用A表示)不存在即A == None或者 A爲空,即len(A) == 0 的狀況。數組
2. 二分法核心找的是mid值,並判斷這個mid是否跟咱們要找的target一致,或者和target之間的關係,因此要先判斷start和end。爲start和end賦值,start = 0, end = len(A) - 1ide
3. 以後就是要進行while循環,目的是用一次次的二分來找出是否存在target或者target的位置、範圍等問題,條件是start + 1 < end來避免死循環oop
並有 mid = start + ( end - start ) / 2 來避免溢出blog
4. 判斷A[mid] 與 target的關係,及採起怎樣的賦值操做來保留有解的一半,即start == mid 或者 end == midelement
5. 可能A[start] 與 A[end]的值與target相同,可是已經使 start + 1 < end 這個條件爲False,因此在循環外還要判斷這兩個值是否和target一致。get
6. 若是都不相等的話則返回空it
下面,給出classical binary search的解法,這是簡單而典型的binary search on index的問題io
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def findPosition(self, A, target): # they are different if A is None or len(A) == 0: return -1 # set start and end end = len(A) - 1 start = 0 # while loop, use start + 1 < end to avoid dead loop while (start + 1 < end): mid = start + ( end - start ) / 2 if A[mid] == target: return mid elif A[mid] > target: # start..mid..end, target in start..mid end = mid else: start = mid if A[start] == target: return start if A[end] == target: return end return -1
由經典算法能夠展開到the first position or the last position,都是binary search on index的典型例子,在這兩種中即便找到了相應的元素爲了判斷是不是最開始或者最後的位置,在第四第五步要有所不一樣~以last position爲例
while (start + 1 < end): mid = start + ( end - start ) / 2 if A[mid] == target: start = mid elif A[mid] > target: # start..mid..end, target in start..mid end = mid else: start = mid if A[end] == target: return end if A[start] == target: return start
比較相似的像 search a 2D matrix 問題,只是把二維數組展開成一個一維數組,繼續採用上面的二分法模板就能夠解
class Solution: """ @param matrix, a list of lists of integers @param target, an integer @return a boolean, indicate whether matrix contains target """ def searchMatrix(self, matrix, target): if matrix is None or len(matrix) == 0: return False m = len(matrix) n = len(matrix[0]) start = 0 end = m * n - 1 while(start + 1 < end): mid = start + (end - start) / 2 line = mid / n column = mid % n if matrix[line][column] == target: return True elif matrix[line][column] < target: start = mid else: end = mid if matrix[(start / n)][(start % n)] == target: return True if matrix[(end / n)][(end % n)] == target: return True return False
search insert position 只要把握住二分法一個重要的特性,就是判斷條件,就能夠轉化爲找first position >= target 的問題
class Solution: """ @param A : a list of integers @param target : an integer to be inserted @return : an integer """ def searchInsert(self, A, target): # find the position whose value is equal or more than target # only consider no duplicates conditions if A is None or len(A) == 0: return 0 start = 0 end = len(A) - 1 while(start + 1 < end): mid = start + (end - start) / 2 if A[mid] >= target: end = mid else: start = mid if A[start] >= target: return start if A[end] >= target: return end # a condition that the target is more than all of the elements in array if A[end] < target: return end + 1 return -1