Java实现lower_bound()和upper_bound()

lower_bound()

https://www.bilibili.com/video/BV1AP41137w7/?spm_id_from=333.788&vd_source=88184dae257eecf4353eecdafc614dd4

函数lower_bound()在**[lo, hi)进行二分查找,返回大于或等于**target的第一个元素的位置。如果所有元素都小于target,则返回hi.

~~private int lower_bound(int[] nums, int lo, int hi, int target) {
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            if (target > nums[mid]) lo = mid + 1;
            else                    hi = mid;
        }
        return lo;~~ 
    }

如果是在[lo, hi]进行二分查找,找第一个 >= target的第一个元素下标。如果所有元素都小于target,则返回0,如果所有元素都大于等于target,则返回 hi+1。

//    [lo , hi]
    private static int lower_bound(int[] nums, int lo, int hi, int target) {
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (nums[mid] < target) lo = mid + 1;
            else                    hi = mid - 1;
        }
        return lo;
    }

upper_bound()

函数upper_bound()在**[lo, hi)进行二分查找,返回大于**target的第一个元素,如果所有元素都小于等于target,则返回hi.

private int upper_bound(int[] nums, int lo, int hi, int target) {
     while (lo < hi) {
         int mid = lo + (hi - lo) / 2;
         if (target >= nums[mid]) lo = mid + 1;
         else                     hi = mid;
     }
     return lo;
 }
<think>好的,用户现在问的是如何在Java实现lower_boundupper_bound,这两个函数在C++的STL中很常见,用于在有序数组中查找插入位置。用户可能已经熟悉C++,现在转到Java,发现没有现成的函数,所以想知道如何自己实现。 首先,我需要确认用户对这两个函数的理解是否正确。lower_bound返回第一个大于或等于目标值的元素位置,而upper_bound返回第一个大于目标值的元素位置。这两个函数在处理有序集合时非常有用,比如二分查找、插入元素或者统计频率等场景。 接下来,用户可能需要在Java实现类似的功能,但Java的标准库并没有直接提供这两个方法。虽然Java有Arrays.binarySearch,但它的返回值处理起来可能不够直观,特别是当元素不存在时,返回的是插入点的负值,需要转换一下。因此,用户可能需要自己实现这两个函数,或者基于现有的binarySearch进行调整。 在实现lower_bound时,标准的二分查找算法可以稍作修改。循环条件应该是low < high,而不是low <= high,这样可以确保循环结束时lowhigh相等。中间值的计算需要注意避免溢出,所以使用位运算或者high - low的方式。当中间元素小于目标值时,移动low,否则移动high,最后返回low的位置。这样可以保证找到第一个不小于目标值的位置。 对于upper_bound实现方式类似,只是在比较时将条件改为中间元素小于等于目标值时移动low,否则移动high。这样循环结束后,low的位置就是第一个大于目标值的位置。 需要注意的是,Java的数组集合可能包含重复元素,这种情况下这两个函数的正确性尤为重要。此外,用户可能希望处理各种数据类型,比如整数、浮点数或者自定义对象,这时候可能需要使用泛型方法,并传递一个比较器Comparator。不过,用户的示例中使用的是整数数组,所以可能暂时不需要泛型实现,但如果有扩展需求,可以提供更通用的代码示例。 另外,用户可能关心边界情况,比如目标值小于所有元素、大于所有元素,或者等于某些元素的情况。需要确保在这些情况下函数仍能正确返回预期的位置。例如,当目标值大于所有元素时,lower_boundupper_bound都应该返回数组长度,表示插入到末尾。 最后,可能需要提供一些使用示例,帮助用户理解如何调用这两个方法,并验证它们的正确性。例如,在有序数组中进行测试,并输出结果是否符合预期。这样用户可以更直观地看到函数的行为,从而更好地应用到自己的项目中。 总结下来,用户的真实需求是在Java实现类似C++的lower_boundupper_bound功能,用于有序数组的查找。需要提供清晰的代码实现,解释其逻辑,并说明注意事项可能的扩展方向。</think>在 Java 中,虽然没有直接提供 `lower_bound` `upper_bound` 函数(如 C++ STL 中的实现),但可以通过 **二分查找** 自行实现这两个功能。以下是实现方法示例: --- ### **1. `lower_bound` 功能** - **定义**:返回第一个 **大于或等于** 目标值的元素位置。 - **实现代码**: ```java public static int lowerBound(int[] nums, int target) { int low = 0, high = nums.length; while (low < high) { int mid = low + (high - low) / 2; // 避免溢出 if (nums[mid] < target) { low = mid + 1; } else { high = mid; } } return low; } ``` --- ### **2. `upper_bound` 功能** - **定义**:返回第一个 **严格大于** 目标值的元素位置。 - **实现代码**: ```java public static int upperBound(int[] nums, int target) { int low = 0, high = nums.length; while (low < high) { int mid = low + (high - low) / 2; if (nums[mid] <= target) { // 注意此处是 <= low = mid + 1; } else { high = mid; } } return low; } ``` --- ### **使用示例** ```java int[] arr = {1, 2, 4, 4, 5}; int target = 4; // lower_bound: 返回第一个 >=4 的位置(索引 2) int lower = lowerBound(arr, target); // upper_bound: 返回第一个 >4 的位置(索引 4) int upper = upperBound(arr, target); System.out.println("lower_bound: " + lower); // 输出 2 System.out.println("upper_bound: " + upper); // 输出 4 ``` --- ### **关键点解释** 1. **循环条件**:`low < high` 确保最终 `low == high`,直接返回即可。 2. **中间值计算**:`mid = low + (high - low) / 2` 避免整数溢出(等同于 `(low + high) / 2`,但更安全)。 3. **边界处理**: - 若所有元素均小于目标值,返回 `nums.length`。 - 若目标值小于所有元素,返回 0。 --- ### **扩展:支持泛型(如 List)** 若需要处理 `List<T>` 或其他数据类型,可以借助 `Comparator` 实现泛型版本: ```java public static <T> int lowerBound(List<? extends T> list, T target, Comparator<? super T> comparator) { int low = 0, high = list.size(); while (low < high) { int mid = low + (high - low) / 2; if (comparator.compare(list.get(mid), target) < 0) { low = mid + 1; } else { high = mid; } } return low; } ``` --- ### **与 Java 内置方法的区别** Java 的 `Arrays.binarySearch` 返回: - 存在目标值时:返回任意一个匹配的索引。 - 不存在时:返回 `(-(插入点) - 1)`。 可以通过以下方式间接实现 `lower_bound`: ```java int pos = Arrays.binarySearch(arr, target); if (pos < 0) pos = -pos - 1; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值