Binary Search 二元搜尋找到最接近的答案
Binary Search 二元搜尋找到最接近的答案
找出 大於等於答案(>= target)
的索引位置,最後回傳 左指標位置 left
就是要找的答案
程式範例
JavaScript
function BinarySearch(searchNumberArray, searchNumber) {
// 左側指標
var leftNumberPointer = 0;
// 右側指標
var rightNumberPointer = searchNumberArray.length - 1;
while (leftNumberPointer <= rightNumberPointer) {
// 中間指標
var middleNumberPointer = Math.floor((rightNumberPointer + leftNumberPointer) / 2);
// 中間指標數字
var middleNumber = searchNumberArray[middleNumberPointer];
if (searchNumber == middleNumber) {
// 如果「要找的數字」與「中間指標數字」相同
// 找到了,回傳這個數字指標位置
return middleNumberPointer;
}
else if (searchNumber < middleNumber) {
// 如果「要找的數字」小於「中間指標數字」
// 表示「中間指標」右邊的所有數字都"大於"「要找的數字」
// 所以將「右側指標」移動到目前「中間指標 - 1」的位置
rightNumberPointer = middleNumberPointer - 1;
}
else {
// 如果「要找的數字」大於「中間指標數字」
// 表示「中間指標」左邊的所有數字都"小於"「要找的數字」
// 所以將「左側指標」移動到目前「中間指標 + 1」的位置
leftNumberPointer = middleNumberPointer + 1;
}
}
// 如果都沒有找到,回傳最接近的指標
return leftNumberPointer;
}
TypeScript
function BinarySearch(searchNumberArray: number[], searchNumber: number){
// 左側指標
let leftNumberPointer: number = 0;
// 右側指標
let rightNumberPointer: number = searchNumberArray.length - 1;
while (leftNumberPointer <= rightNumberPointer) {
// 中間指標
let middleNumberPointer = Math.floor((rightNumberPointer + leftNumberPointer) / 2);
// 中間指標數字
let middleNumber = searchNumberArray[middleNumberPointer];
if (searchNumber == middleNumber) {
// 如果「要找的數字」與「中間指標數字」相同
// 找到了,回傳這個數字指標位置
return middleNumberPointer;
} else if (searchNumber < middleNumber) {
// 如果「要找的數字」小於「中間指標數字」
// 表示「中間指標」右邊的所有數字都"大於"「要找的數字」
// 所以將「右側指標」移動到目前「中間指標 - 1」的位置
rightNumberPointer = middleNumberPointer - 1;
} else {
// 如果「要找的數字」大於「中間指標數字」
// 表示「中間指標」左邊的所有數字都"小於"「要找的數字」
// 所以將「左側指標」移動到目前「中間指標 + 1」的位置
leftNumberPointer = middleNumberPointer + 1;
}
}
// 如果都沒有找到,回傳最接近的指標
return leftNumberPointer;
}
說明
left
和 right
代表著可能含有答案的閉區間
,所以答案一定在這個範圍內
對任何一個數字,假如一直找不到,這個區間會不斷減小,直到走到 left == right
,此時區間內只剩下 1 個數字。
有可能最終大於
、等於
、或小於
我們要找的 target
,最接近的答案表示沒有 等於
,只有可能是 大於
或 小於
最後的左右指標區間數值,大於
要找的數字
最後左右指標數字 6
大於 要找的數字 5.5
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
指標位置 | 左指標 == 右指標 |
如果大於 target
,我們會讓 right = mid - 1
,而 left 不變
left
繼續停留在我們想要的位置上
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
指標位置 | 右指標 |
左指標 |
最後的左右指標區間數值,小於
要找的數字
最後左右指標數字 6
小於 要找的數字 6.5
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
指標位置 | 左指標 == 右指標 |
如果小於 target
,我們會讓 left = mid + 1
而 right 不變
剛好把
left
移到我們想要的位置上
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
指標位置 | 右指標 |
左指標 |
最後的左右指標區間數值,小於
要找的數字,數值比陣列大
最後左右指標數字 9
小於 要找的數字 99
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
指標位置 | 左指標 == 右指標 |
如果小於 target
,我們會讓 left = mid + 1
而 right 不變
剛好把
left
移到我們想要的位置上
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
指標位置 | 右指標 |
左指標 |
找出 大於等於答案(>= target)
的索引位置,而陣列中都沒有這個數字,所以 left
會超出陣列 1 格
最後的左右指標區間數值,大於
要找的數字,數值比陣列小
最後左右指標數字 6
大於 要找的數字 -1
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
指標位置 | 左指標 == 右指標 |
如果大於 target
,我們會讓 right = mid - 1
,而 left 不變
left
繼續停留在我們想要的位置上
索引 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|---|
數字陣列 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
指標位置 | 右指標 |
左指標 |