简单记录几种二分-java

本文深入讲解了二分搜索算法的不同应用场景,包括查找相同键值的最小和最大下标、小于键值的最大下标以及大于键值的最小下标。通过具体实现代码,详细解释了如何在已排序数组中高效地进行这些操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 实现的各种二分查找方法解析

在算法与数据结构中,二分查找是一种常用且高效的搜索技术。本文详细解析 Java 实现的几种二分查找方法,涵盖不同场景下的应用:

  • 查找相同 key 的最小下标和最大下标。
  • 查找小于 key 的最大下标。
  • 查找大于 key 的最小下标。

核心思路

二分查找的基本思想是:

  1. 将搜索范围从中间分为两半,依次缩小范围。
  2. 根据条件调整左指针 l 或右指针 r
  3. 循环结束时确定结果。

下面代码展示了不同场景下的二分查找方法。


完整代码

/**
 * 各种二分查找方法实现
 * 包括:
 * 1. 查找相同 key 的最小和最大下标。
 * 2. 查找小于 key 的最大下标。
 * 3. 查找大于 key 的最小下标。
 * 适用于升序排序的数组。
 */
public class BinSearch {

    /**
     * 查找相同 key 的最小下标
     * 思路:向左不断收缩范围,最后的位置即为结果
     */
    public static int low_search(int[] arr, int key) {
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (arr[mid] >= key) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        if (l < arr.length && arr[l] == key) {
            return l;
        }
        return -1;
    }

    /**
     * 查找相同 key 的最大下标
     * 思路:向右不断收缩范围,最后的位置即为结果
     */
    public static int high_search(int[] arr, int key) {
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (arr[mid] > key) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        if (r >= 0 && arr[r] == key) {
            return r;
        }
        return -1;
    }

    /**
     * 查找小于 key 的最大下标
     * 思路:当值大于等于 key 时向左收缩,否则向右收缩。
     */
    public static int small_search(int[] arr, int key) {
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (arr[mid] >= key) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return r; // r 越界时为 -1,直接返回
    }

    /**
     * 查找大于 key 的最小下标
     * 思路:当值小于等于 key 时向右收缩,否则向左收缩。
     */
    public static int big_search(int[] arr, int key) {
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (arr[mid] > key) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return l >= arr.length ? -1 : l; // 如果越界,返回 -1
    }
}

详细解析

方法一:查找相同 key 的最小下标

核心逻辑
  • 目标:找到第一个等于 key 的元素。
  • 每次检查 arr[mid] 是否大于等于 key,如果是,则向左收缩范围,否则向右收缩。
示例

输入数组:[1, 2, 2, 2, 3]key = 2

  • 输出结果:1(第一个 2 的下标)

方法二:查找相同 key 的最大下标

核心逻辑
  • 目标:找到最后一个等于 key 的元素。
  • 每次检查 arr[mid] 是否小于等于 key,如果是,则向右收缩范围,否则向左收缩。
示例

输入数组:[1, 2, 2, 2, 3]key = 2

  • 输出结果:3(最后一个 2 的下标)

方法三:查找小于 key 的最大下标

核心逻辑
  • 目标:找到所有小于 key 的元素中最大的下标。
  • 每次检查 arr[mid] 是否大于等于 key,如果是,则向左收缩范围,否则向右收缩。
示例

输入数组:[1, 2, 3, 4, 5]key = 4

  • 输出结果:2(下标对应值为 3)

方法四:查找大于 key 的最小下标

核心逻辑
  • 目标:找到所有大于 key 的元素中最小的下标。
  • 每次检查 arr[mid] 是否小于等于 key,如果是,则向右收缩范围,否则向左收缩。
示例

输入数组:[1, 2, 3, 4, 5]key = 3

  • 输出结果:3(下标对应值为 4)

总结

  1. 二分查找的灵活性:通过调整条件,二分查找可以适配多种场景。
  2. 边界处理:实现时需注意数组越界情况,例如返回值为 -1 表示查找失败。
  3. 性能优势:二分查找时间复杂度为 O(log n),适用于大规模数据的搜索。

通过以上实现,您可以轻松解决数组中的多种查找需求。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值