W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
「二分查找 binary search」是一種基于分治策略的高效搜索算法。它利用數(shù)據(jù)的有序性,每輪減少一半搜索范圍,直至找到目標元素或搜索區(qū)間為空為止。
Question
給定一個長度為 n 的數(shù)組 nums ,元素按從小到大的順序排列,數(shù)組不包含重復元素。請查找并返回元素 target 在該數(shù)組中的索引。若數(shù)組不包含該元素,則返回 ?1 。
圖 10-1 二分查找示例數(shù)據(jù)
如圖 10-2 所示,我們先初始化指針
接下來,循環(huán)執(zhí)行以下兩步。
a. 當 nums[m] < target 時,說明 target 在區(qū)間 [m+1,j] 中,因此執(zhí)行 i=m+1 。
b. 當 nums[m] > target 時,說明 target 在區(qū)間 [i,m?1] 中,因此執(zhí)行 j=m?1 。
c. 當 nums[m] = target 時,說明找到 target ,因此返回索引 m 。
若數(shù)組不包含目標元素,搜索區(qū)間最終會縮小為空。此時返回 ?1 。
圖 10-2 二分查找流程
值得注意的是,由于 i 和 j 都是 int 類型,因此 i+j 可能會超出 int 類型的取值范圍。為了避免大數(shù)越界,我們通常采用公式 m=?i+(j?i)/2? 來計算中點。
binary_search.cpp
/* 二分查找(雙閉區(qū)間) */
int binarySearch(vector<int> &nums, int target) {
// 初始化雙閉區(qū)間 [0, n-1] ,即 i, j 分別指向數(shù)組首元素、尾元素
int i = 0, j = nums.size() - 1;
// 循環(huán),當搜索區(qū)間為空時跳出(當 i > j 時為空)
while (i <= j) {
int m = i + (j - i) / 2; // 計算中點索引 m
if (nums[m] < target) // 此情況說明 target 在區(qū)間 [m+1, j] 中
i = m + 1;
else if (nums[m] > target) // 此情況說明 target 在區(qū)間 [i, m-1] 中
j = m - 1;
else // 找到目標元素,返回其索引
return m;
}
// 未找到目標元素,返回 -1
return -1;
}
時間復雜度 O(log?n) :在二分循環(huán)中,區(qū)間每輪縮小一半,循環(huán)次數(shù)為 log2?n 。
空間復雜度 O(1) :指針 i 和 j 使用常數(shù)大小空間。
binary_search.cpp
/* 二分查找(左閉右開) */
int binarySearchLCRO(vector<int> &nums, int target) {
// 初始化左閉右開 [0, n) ,即 i, j 分別指向數(shù)組首元素、尾元素+1
int i = 0, j = nums.size();
// 循環(huán),當搜索區(qū)間為空時跳出(當 i = j 時為空)
while (i < j) {
int m = i + (j - i) / 2; // 計算中點索引 m
if (nums[m] < target) // 此情況說明 target 在區(qū)間 [m+1, j) 中
i = m + 1;
else if (nums[m] > target) // 此情況說明 target 在區(qū)間 [i, m) 中
j = m;
else // 找到目標元素,返回其索引
return m;
}
// 未找到目標元素,返回 -1
return -1;
}
如圖 10-3 所示,在兩種區(qū)間表示下,二分查找算法的初始化、循環(huán)條件和縮小區(qū)間操作皆有所不同。
由于“雙閉區(qū)間”表示中的左右邊界都被定義為閉區(qū)間,因此指針 i 和 j 縮小區(qū)間操作也是對稱的。這樣更不容易出錯,因此一般建議采用“雙閉區(qū)間”的寫法。
圖 10-3 兩種區(qū)間定義
二分查找在時間和空間方面都有較好的性能。
然而,二分查找并非適用于所有情況,主要有以下原因。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: