Binary Search 二元搜寻找到最接近的答案
Binary Search 二元搜寻找到最接近的答案
Categories:
找出 大于等于答案(>= 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 | |
指标位置 | 右指标 |
左指标 |