【JavaScript】JS二分搜索算法:基本二分搜索、寻找左侧边界的二分搜索、寻找右侧边界的二分搜索
本文介绍关于JS 中常见3种类型的二分搜索算法,需要的朋友可以参考一下:
目录
1、基本二分搜索
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).valuevoid async function () {let nums = (await readline()).split(' ').map(Number)let target = Number(await readline())console.log(binarySearch(nums, target))
}()// 通过基本的二分搜索寻找一个数返回其下标
function binarySearch (nums, target) {let left = 0let right = nums.length - 1while (left <= right) {let mid = parseInt((left + right) / 2, 10)if (nums[mid] === target) {return mid} else if (nums[mid] > target) {// 在左侧right = mid - 1} else if (nums[mid] < target) {// 在右侧left = mid + 1}}// target不存在return -1
}
用例测试1:
1 2 3 4 5
4
3
用例测试2:
1 2 3 4 5
8
-1
2、寻找左侧边界的二分搜索
取[left, right)区间
该方法所取区间为左闭右开区间,其终止条件是left 等于 right。能够搜索左边界的原因是其在遇到nums[mid] == target时不会立即返回,而是缩小搜索区间的上界right,在区间[left, mid)中继续搜索,即不断向左收缩,以此达到锁定左侧边界的目的。如果target比所有数都大,此时返回的索引将会是nums.length则证明没找到,返回-1。如果找到的数比所有的都小,将会返回索引为0,此时需要进行判断索引为0时是否是target值。
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).valuevoid async function () {let nums = (await readline()).split(' ').map(Number)let target = Number(await readline())console.log(leftBound(nums, target))
}()// 寻找左侧边界的二分搜索[left, right)
function leftBound (nums, target) {if (nums.length === 0) {return -1}let left = 0let right = nums.lengthwhile (left < right) {let mid = parseInt((left + right) / 2, 10)if (nums[mid] === target) {right = mid} else if (nums[mid] < target) {left = mid + 1} else if (nums[mid] > target) {right = mid}}// 如果left为nums.length则证明没找到,返回-1if (left === nums.length) {return -1}// 判断索引为0时值是否为targetreturn nums[left] === target ? left : -1
}
用例测试:
1 2 2 2 3
2
1
取[left, right]区间
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).valuevoid async function () {let nums = (await readline()).split(' ').map(Number)let target = Number(await readline())console.log(leftBound(nums, target))
}()// 寻找左侧边界的二分搜索[left, right]
function leftBound(nums, target) {let left = 0;let right = nums.length - 1;while (left <= right) {const mid = parseInt((left + right) / 2, 10);if (nums[mid] === target) {right = mid - 1;} else if (nums[mid] > target) {right = mid - 1;} else if (nums[mid] < target) {left = mid + 1;}}if (left >= nums.length || nums[left] !== target) {return -1;}return left;
}
用例测试:
1 2 2 2 3
2
1
3、寻找右侧边界的二分搜索
取[left, right)区间
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).valuevoid async function () {let nums = (await readline()).split(' ').map(Number)let target = Number(await readline())console.log(rightBound(nums, target))
}()function rightBound(nums, target) {if (nums.length === 0) {return -1;}let left = 0;let right = nums.length;while (left < right) {const mid = parseInt((left + right) / 2, 10);if (nums[mid] === target) {left = mid + 1;} else if (nums[mid] < target) {left = mid + 1;} else if (nums[mid] > target) {right = mid;}}return left - 1;
}
用例测试:
1 2 2 2 3
2
1
取[left, right]区间
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).valuevoid async function () {let nums = (await readline()).split(' ').map(Number)let target = Number(await readline())console.log(rightBound(nums, target))
}()function rightBound(nums, target) {let left = 0;right = nums.length - 1;while (left <= right) {const mid = parseInt((left + right) / 2, 10);if (nums[mid] === target) {left = mid + 1;} else if (nums[mid] < target) {left = mid + 1;} else if (nums[mid] > target) {right = mid - 1;}}if (right < 0 || nums[right] !== target) {return -1;}return right;
}
用例测试:
1 2 2 2 3
2
1
总结
到此关于JavaScript中3种常见类型二分搜索算法的介绍就结束了,更多关于JS算法刷题常用知识点后续还会更新,在阅读过程中如若有误,劳请指正;如若有妙解、疑惑也欢迎大家和我交流,感谢!