基本的解決方法就是利用二分法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int io=0,hi=nums.size(),mi;
while(io<hi)
{
mi=(io+hi)>>1;
if(nums[mi]==target)return mi;
else if(nums[mi]>target)
hi=mi;
else
io=mi+1;
}
if(nums[mi]==target)return mi;
else return -1;
}
};
二分查找的基本形式比較的固定,主要就是while循環裏的那三個判斷(也有的方法是取消掉返還mi那個判斷,但我覺得好像不太直觀容易出錯),但還是有幾個細節問題:
一 .中間值mi的問題
主要有三種形式:
1.mi=(io+hi)/2
2.mi=io+(hi-io)/2
3.mi=(io+hi)>>1
爲了避免出現溢出的情況出現,第2種是比較好的選擇
二.查找區間的邊界如何選擇
邊界的選取同時也有三種:
- 左開右閉
(io,hi]
- 左閉右開
[io,hi)
- 左右均閉
[io,hi]
具體如何選擇,結合實際問題分析,有時候對同一個問題三種形式都是可行的,但是每一種形式對應的while終止條件,hi,io
的迭代更新和最後的返回值是不盡相同的,下面具體分析一下:
首先對於(io,hi],
基本模板爲:
while(io<hi) //終止條件
{
if(if(nums[mi]==target) return mi;
else if(nums[mi]>target)
hi=mi-1; //hi更新
else
io=mi; //io更新
}
對於[io,hi),
基本模板爲:
while(io<hi) //終止條件
{
if(if(nums[mi]==target) return mi;
else if(nums[mi]>target)
hi=mi; //hi更新
else
io=mi+1; //io更新
}
對於[io,hi),
基本模板爲:
while(io<=hi) //終止條件
{
if(if(nums[mi]==target) return mi;
else if(nums[mi]>target)
hi=mi-1; //hi更新
else
io=mi+1; //io更新
}