二分查詢是一種非常簡單易懂的快速查詢演算法,時間複雜度為o(logn),這是相當快的了。利用二分思想,即便猜乙個 0 到 999 的數字,最多也只要 10 次就能猜中。
基本形式**:
//在有序不重複元素中尋找指定值的位置,不存在返回-1
intbsearch
(vector<
int>
& nums,
int val)
else
if(nums[mid]
< val)
else
}return-1
;}
注意方面:二分查詢轉遞迴形式:
//遞迴形式的二分查詢
intbsearchinternally
(vector<
int>
&nums,
int left,
int right,
int val)
int mid = left +
((right- left)
>>1)
;if(nums[mid]
== val)
else
if(nums[mid]
< val)
else
}
二分查詢的侷限性:
有時候我們需要查詢的並不是乙個有序無重複陣列種的某個值,而是在乙個有序有重複陣列種查詢位於最前面的某個值等等…因此,就出現了常見的4種變形問題:
其實這只是對基本二分查詢的變形,但是不注意也會有很多錯誤,下面貼上**:
//**查詢第乙個值等於給定值的元素**
intbsearchfirst
(vector<
int>
& nums,
int val)
else
if(nums[mid]
> val)
else
}return-1
;}
如果我們查詢的是任意乙個值等於給定值的元素,當 nums[mid]等於要查詢的值時,nums[mid]就是我們要找的元素。但是,如果我們求解的是第乙個值等於給定值的元素,當 nums[mid]等於要查詢的值時,我們就需要確認一下這個 nums[mid]是不是第乙個值等於給定值的元素。
我們重點看if (mid == 0 || nums[mid - 1] != val)
行**。如果 mid 等於 0,那這個元素已經是陣列的第乙個元素,那它肯定是我們要找的;如果 mid 不等於 0,但 nums[mid]的前乙個元素 nums[mid-1]不等於 value,那也說明 nums[mid]就是我們要找的第乙個值等於給定值的元素。
如果經過檢查之後發現 nums[mid]前面的乙個元素 nums[mid-1]也等於 value,那說明此時的 nums[mid]肯定不是我們要查詢的第乙個值等於給定值的元素。那我們就更新 high=mid-1,因為要找的元素肯定出現在[low, mid-1]之間。
同樣的,查詢最後乙個值等於給定值的元素也和上述思路相同。
//**查詢最後乙個值等於給定值的元素**
intbsearchlast
(vector<
int>
& nums,
int val)
else
if(nums[mid]
> val)
else
else}}
return-1
;}
//**查詢第乙個大於等於給定值的元素**
intbsearchoverfirst
(vector<
int>
&nums,
int val)
right = mid -1;
}else
}return-1
;}
//**查詢最後乙個小於等於給定值的元素**
intbsearchoverlast
(vector<
int>
& nums,
int val)
left = mid +1;
}else
}return-1
;}
#define accuracy 1e-7
bool
equal
(double a,
double b)
double
mysqrt
(double val)
else
}return left;
}
測試cout
我們可以在常規二分查詢的時候檢視當前 mid 為分割位置分割出來的兩個部分 [l, mid] 和 [mid + 1, r] 哪個部分是有序的,並根據有序的那個部分確定我們該如何改變二分查詢的上下界
,因為我們能夠根據有序的那部分判斷出 target 在不在這個部分:如果[l, mid - 1]
是有序陣列,且 target 的大小滿足[nums[l],nums[mid])
,則我們應該將搜尋範圍縮小至[l, mid - 1]
,否則在[mid + 1, r]
中尋找。
如果[mid, r]
是有序陣列,且 target 的大小滿足(nums[mid+1],nums[r]]
,則我們應該將搜尋範圍縮小至[mid + 1, r]
,否則在[l, mid - 1]
中尋找。
演算法總結 二分查詢
本文首發於我的個人部落格 尾尾部落 二分查詢法作為一種常見的查詢方法,將原本是線性時間提公升到了對數時間範圍,大大縮短了搜尋時間,但它有乙個前提,就是必須在有序資料中進行查詢。二分查詢很好寫,卻很難寫對,據統計只有10 的程式設計師可以寫出沒有bug的的二分查詢 出錯原因主要集中在判定條件和邊界值的...
二分查詢 演算法總結
二分查詢也稱折半搜尋,是一種在有序陣列中查詢某一特定的元素的搜尋演算法。class solution else if nums mid mid left right 2 在left和right都很大的時候會出現溢位的情況,從而導致陣列訪問溢位。改進方法將加法變為減法 mid left right l...
演算法總結 二分查詢
二分查詢法作為一種常見的查詢方法,將原本是線性時間提公升到了對數時間範圍,大大縮短了搜尋時間,但它有乙個前提,就是必須在有序資料中進行查詢。二分查詢很好寫,卻很難寫對,據統計只有10 的程式設計師可以寫出沒有bug的的二分查詢 出錯原因主要集中在判定條件和邊界值的選擇上,很容易就會導致越界或者死迴圈...