二分查詢的前提:
1.目標函式單調性(單調遞增或遞減)
2.存在上下界(bounded)
3.能夠通過索引訪問(index accessible)
**模版
left , right = 0,len(array) - 1
while left <= right:
mid = (left+right) / 2
if array[mid] == target:
# find the target!!
break or return result
elif array[mid] < target:
left = mid + 1
else:
right = mid - 1
例題1 :新增鏈結描述
33.搜尋旋轉排序陣列
題目描述:假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1 。
你可以假設陣列中不存在重複的元素。
你的演算法時間複雜度必須是 o(log n) 級別。
示例 1::
輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4
示例 2:
輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1
題解:題目要求時間複雜度為o(log n),故用二分查詢,定義三個變數:left right mid 來判斷指標向後還是向前規約
如果target在[mid+1,right]序列中,則 left=mid+1,否則right=mid,判斷target在[mid+1,right]序列中的方式如下:
①如果[0,mid]為公升序序列即nums[0]<=nums[mid] 時 :若 target>nums[mid]||targetnums[mid] 時 :若 targetmums[mid]) ,向後規約
③其餘情況為向前規約
迴圈判斷,排除剩餘最後乙個元素時退出迴圈,找到返回下標,未找到返回-1
實現:二分法( 時間複雜度為o(log(n)) , 執行時間 0ms)
public int search(int nums, int target) else if (target > nums[mid] && target < nums[0]) else
} return left == right && nums[left] == target ? left : -1;
}}
例題2:
新增鏈結描述
69.x的平方根
題目描述:實現 int sqrt(int x) 函式。 計算並返回 x 的平方根,其中 x 是非負整數。
由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。
示例 1: 輸入: 4
輸出: 2
示例 2: 輸入: 8
輸出: 2
說明: 8 的平方根是 2.82842…, 由於返回型別是整數,小數部分將被捨去。
實現:解法方案一:二分法( 時間複雜度為o(lg(x)) , 執行時間 2ms)
public int mysqrt(int x) else if (mid < x / mid) else
} return right;
}
解決方案二:牛頓法(時間複雜度o(lg(x)) , 執行時間 2ms)
public int mysqrt(int x)
解決方案三:暴力(時間複雜度o(sqrt(x)) , 執行時間 178ms)
public int mysqrt(int x)
力扣 二分查詢
1.確定二分的邊界 2.編寫二分的 框架 3.設計乙個check 性質 4.判斷一下區間如何更新 5.如果更新方式時l mid,r mid 1,那麼在算mid的時候加1 includeusing namespace std int mysqrt int x return l int main ret...
力扣 二分應用題
1.875.愛吃香蕉的珂珂,傳統二分,左閉右開,返回left right即可。2.222.完全二叉樹的節點個數,利用完全二叉樹結合二分,位運算,注意level 0的特殊情況,返回left 1。需要靈活運用二分查詢。3.69.x 的平方根,上限粗略定為x,注意迴圈條件 l r的賦值 返回結果。4.74...
二分查詢的特性及應用
如果我們熟悉二分查詢,我們就知道二分查詢有乙個重要的基礎,就是需要有序的順序表。這裡有兩點,乙個是有序,另乙個是順序表。一般來說,只要是查詢的題目,和這兩者掛上鉤,基本就是二分查詢無疑了。因為二分查詢過於重要,建議大家自己要能寫出 統計乙個數字在乙個排序陣列 現的次數。如果說從前往後掃瞄乙個陣列,統...