首先來談一下二分查詢的模板問題。一般會出現一下三種錯誤:
1、陣列越界。
2、死迴圈
3、跳過查詢的元素下標。
先來看幾組常見容易出錯的模板。
int low=0,high=n;這時這個模板已經很完美了,只要陣列的長度不為0時,等式永遠成立,但還是存在一定缺陷的,比如[1]中找0元素,那麼high會變成-1,導致溢位,所以通常還要加位址合法判斷條件,但畢竟也不是什麼大問題。while(low這種情況下,如果在[2,2]中找值為3的下標,那麼每次都會讓low的值等於mid,使low和high緊挨在一起,永遠也退不出去,造成死迴圈。
那如果我每次讓它進1減1尼?
int low=0,high=n;
while(low這總不會出問題了吧。。。可還是會出問題。還是例子說話,比如說[1,2,2,3]裡找最後乙個值為2的元素。有這樣的二分查詢程式
會出現什麼結果尼?int low=
0,high=n;
while
(low
//根據條件返回low和high
返回來的是下標為3的值,而不是2。(為什麼不能返回mid?多加幾個2試一下就可以知道返回mid也不滿足題目要求)。
接下來就是現在最常見的版本
int low=0,high=n;
while(low<=high)
最後講到模板問題,雖然解決問題時應該隨機應變,根據具體問題調整。但乙個好的模板能讓我們不用去關心**內部實現,大大降低了我們解決問題時的思維複雜度。
int low=0,high=n;while(low+1這個模板的優點在於,low和high是緊挨著的兩個下標,我們不用關心是否需要mid+1/-1,自然也不需要擔心low/high會越界,只需要具體問題套模板即可。
下面具體在練習題中體會各個模板在實現具體問題的不同。
leetcode 278題 第乙個錯誤的版本。
你是產品經理,目前正在帶領乙個團隊開發新的產品。不幸的是,你的產品的最新版本沒有通過質量檢測。由於每個版本都是基於之前的版本開發的,所以錯誤的版本之後的所有版本都是錯的。
假設你有 n 個版本 [1, 2, …, n],你想找出導致之後所有版本出錯的第乙個錯誤的版本。
你可以通過呼叫 bool isbadversion(version) 介面來判斷版本號 version 是否在單元測試**錯。實現乙個函式來查詢第乙個錯誤的版本。你應該儘量減少對呼叫 api 的次數。
版本一
版本二// forward declaration of isbadversion api.
bool
isbadversion
(int version)
;class
solution
return low;}}
};
對比兩個版本來說,版本一需要判定n的值是否為1(為1時二分查詢下標會越界),而版本二則避免了這個問題。bool
isbadversion
(int version)
;class
solutionif(
isbadversion
(low)
)return low;
else
return high;}}
;
leetcode34題 在排序陣列中查詢的第乙個和最後乙個位置
給定乙個按照公升序排列的整數陣列 nums,和乙個目標值 target。找出給定目標值在陣列中的開始位置和結束位置。
你的演算法時間複雜度必須是 o(log n) 級別。
如果陣列中不存在目標值,返回 [-1, -1]。
示例 1:
輸入: nums = [5,7,7,8,8,10], target = 8
輸出: [3,4]
示例 2:
輸入: nums = [5,7,7,8,8,10], target = 6
輸出: [-1,-1]
版本一
版本二class
solution
else low=mid;}if
(nums[low]
==target)
result[0]
=low;
else
if(nums[high]
==target)
result[0]
=high;
while
(slow+
1if(nums[shigh]
==target)
result[1]
=shigh;
else
if(nums[slow]
==target)
result[1]
=slow;
return result;}}
;
相比較於版本一,版本二就更繁瑣一些了,不僅需要判斷陣列中只為乙個元素時的情況,而且還需要預防陣列越界的情況,實現時需要考慮的細節比較多,相比較下,還是版本一的模板更方便些。class
solution
return result;
}else
else
low = mid +1;
}if(low>n-1)
//[2,2]找2時high=-1,找3時low=2,所以當low越界時,就表明陣列中無此元素。
return result;
if(nums[low]
== target)
else
return result;
while
(slow <= shigh)
if(shigh<0)
return result;
if(nums[shigh]
== target)
return result;}}
};
240 搜尋二維矩陣||
**編寫乙個高效的演算法來搜尋 m x n 矩陣 matrix 中的乙個目標值 target。該矩陣具有以下特性:
每行的元素從左到右公升序排列。
每列的元素從上到下公升序排列。
示例:現有矩陣 matrix 如下:
[[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]給定 target = 5,返回 true。
給定 target = 20,返回 false。
思路:本題有乙個巧妙的解法,我們可以從右上角或者左下角開始搜尋,當前元素大於targe時。
當當前下標元素值小於targe時
這樣我們每次都可以遍歷一行或者一列,時間複雜度為o(row+col)
class
solution
return
false;}}};
LeetCode刷題總結 二分查詢
leetcode 刷題總結 二分查詢 二分主要是形成自己的 風格就可以了。常用兩種風格 現在偏向於風格一實現了 leetcode35.搜尋插入位置 給定乙個排序陣列和乙個目標值,在陣列中找到目標值,並返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。這個實際上就是手動實現lower...
leetcode刷題 演算法(4) 二分查詢
尋找乙個數 基本的二分搜尋 因為我們初始化 right nums.length 1 所以決定了我們的 搜尋區間 是 left,right 所以決定了 while left right 同時也決定了 left mid 1 和 right mid 1 因為我們只需找到乙個 target 的索引即可,所以...
LeetCode 查詢 二分查詢
給定乙個 n 個元素有序的 公升序 整型陣列 nums 和乙個目標值 target 寫乙個函式搜尋 nums 中的 target,如果目標值存在返回下標,否則返回 1。示例 輸入 nums 1,0,3,5,9,12 target 9 輸出 4 解釋 9 出現在 nums 中並且下標為 4 輸入 nu...