二分法适合哪种情况

二分法(Binary Search)适用于 有序单调性(单调递增/递减) 的问题,它可以 快速 缩小搜索范围,时间复杂度为 O(log n),比线性查找 O(n) 更高效。

📌 适用场景

✅ 1. 在有序数组/列表中查找元素

如果数组是 升序降序 排列的,可以使用二分查找快速找到目标值。

function binarySearch(arr, target) {
    let left = 0, right = arr.length - 1;
    while (left <= right) {
        let mid = Math.floor((left + right) / 2);
        if (arr[mid] === target) return mid;
        if (arr[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1; // 没找到
}

console.log(binarySearch([1, 3, 5, 7, 9], 5)); // 输出 2
console.log(binarySearch([1, 3, 5, 7, 9], 6)); // 输出 -1

✅ 2. 处理“最接近”或“最小满足条件”的问题

比如 “求最小的 x,使得 f(x) 满足某个条件”,可用 二分答案 来优化搜索。

示例:寻找数组中 ≥ target 的最小元素
function lowerBound(arr, target) {
    let left = 0, right = arr.length;
    while (left < right) {
        let mid = Math.floor((left + right) / 2);
        if (arr[mid] >= target) right = mid;
        else left = mid + 1;
    }
    return left;
}

console.log(lowerBound([1, 3, 5, 7, 9], 6)); // 输出 3 (索引 3 处是 7)

✅ 3. 处理最大值/最小值优化问题

当一个函数 f(x) 在区间 [left, right]单调递增/递减,可以用二分查找最优解。

示例:最小长度的子数组(优化 O(n log n))

可以用二分优化 minSubArrayLen(之前用滑动窗口 O(n))。

var minSubArrayLen = function(target, nums) {
    let prefixSum = [0];
    for (let num of nums) prefixSum.push(prefixSum[prefixSum.length - 1] + num);

    let ans = Infinity;
    for (let i = 0; i < nums.length; i++) {
        let left = i + 1, right = nums.length, best = -1;
        while (left <= right) {
            let mid = Math.floor((left + right) / 2);
            if (prefixSum[mid] - prefixSum[i] >= target) {
                best = mid;
                right = mid - 1;
            } else left = mid + 1;
        }
        if (best !== -1) ans = Math.min(ans, best - i);
    }
    return ans === Infinity ? 0 : ans;
};

🚫 二分法不适用的情况

❌ 1. 无法定义单调关系

如果数据没有 单调递增/递减 规律,二分法无法缩小范围。例如:

  • 查找 无序数组 中的元素(需要 O(n) 遍历)
  • 解决 背包问题组合问题(需要 DFSDP

❌ 2. 目标数据动态变化

如果数据在查找过程中不断变化(如流式数据、在线搜索),二分法通常不适用。

🔹 总结

二分法适用于:已排序的数组(经典查找)
满足单调性的函数/问题(二分答案)
求解“最小满足”或“最大满足”条件的问题

不适用于:无序数据(找不到规律)
数据动态变化(二分范围会失效)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值