java 二分法思想

 /**
     * 二分法找值
     * @param arr
     * @param item
     * @return  下标位置
     */
    public static int binary_search(int [] arr,int item){
        int result = -1;
        int low = 0; //最小下标
        int high = arr.length - 1;//最大下标
        while (low <= high) {
            int mid = (low + high) / 2;
            int guss = arr[mid];
            if (guss == item) {
                return mid;
            }
            //猜想的数比 item 大
            if (guss >= item) {
                high =mid-1;
            }else{
                //猜想的数比 item 小
                low=mid+1;
            }
        }
        return result;
    }
    public static void main(String [] args){
        /**
         * 思想:
         *      在一组有序数组中,
         *      (首次最小下标 + 最大下标)/2 获取向下取整的下标
         *      再比较对应是否相等,
         *      1.猜想的值 比目标值大,说明目标值的下标范围在:0 - 向下取整范围;
         *      2.猜想的值 比目标值小,说明目标值的下标范围在:向下取整范围 - 最大下标;
         *      类推
         */
        int [] arr={1,3,2,5,7,11,89,12,78};
        Arrays.sort(arr);
        int i = binary_search(arr, 89);
        System.out.println(i);
    }

扩展:

让我想到一个面试分享的试题: 在一百层高楼,给你两块玻璃,如何快速找到玻璃破碎的临界点?

二分法,第一块玻璃在50层楼时,往下扔,

        1).玻璃破碎,说明临界点在:1 -50 层;第二块,从1层开始一步步测试;

        2 ). 玻璃没有破碎,那么临界点在:51 -100 层,然后再次二次二分法,再次测试

 

 

### 使用 Java 实现二分查找来确定数组中的最大值 在讨论如何使用二分查找算法找到数组或列表的最大值之前,需要注意的是,传统的二分查找算法主要用于在一个有序数组中快速定位目标值的位置。然而,在一个无序的数组中直接应用二分查找并不适用,因为该方法依赖于数组已排序的前提条件。 如果数组已经是升序排列,则可以直接返回最后一个元素作为最大值[^1]。但如果数组未排序或者需要通过某种方式利用二分查找的思想来找最大值,可以考虑以下两种场景: #### 场景一:旋转排序数组 对于某些特殊类型的数组(如经过一次旋转后的升序数组),可以通过修改标准的二分查找逻辑来高效地找出其中的最大值。以下是具体实现思路和代码示例: ```java public class FindMaxInRotatedArray { public static int findMax(int[] nums) { if (nums == null || nums.length == 0) { throw new IllegalArgumentException("Input array is empty or null"); } int low = 0; int high = nums.length - 1; while (low < high) { // 只有当区间长度大于1时才继续循环 int mid = low + (high - low) / 2; if (nums[mid] > nums[high]) { // 如果mid位置的数比最右端大,说明最大值位于右侧子数组 low = mid + 1; } else { // 否则,最大值可能就在左侧子数组或者是当前mid处 high = mid; } } return nums[low]; // 此时low==high,即为最大值所在索引 } public static void main(String[] args){ int[] testArr={3,4,5,1,2}; System.out.println(findMax(testArr)); // 输出应为5 } } ``` 上述代码适用于处理像 `[3, 4, 5, 1, 2]` 这样的旋转排序数组。它假设输入是一个由单增序列构成并被旋转过的数组,并且不包含重复项。这种方法的时间复杂度仍保持 O(log n)[^2]。 #### 场景二:通用解法 —— 非特定结构化数据集 如果没有关于数组任何额外的信息(比如是否已被部分排序等特性),那么无法借助传统意义上的“二分”概念去优化求解过程;此时只能遍历整个集合以获取全局极值点。尽管如此,我们仍然能够设计一种基于比较操作的技术框架来进行简化分析流程如下所示: ```java public class MaxValueFinder{ public static Integer getMax(Integer[] arr){ if(arr ==null||arr.length<=0){ return null;// 或者抛出自定义异常 } int max=arr[0]; for(int i=1;i<arr.length;i++){ if(max<arr[i]){ max=arr[i]; } } return max; } public static void main(String []args){ Integer[] data=new Integer[]{7,-89,65,23,12}; System.out.print(getMax(data));// 应打印出65 } } ``` 此版本没有任何前提约束条件下均可正常工作,但其时间效率降级至O(n),因为它实际上执行了一次完整的线性扫描动作[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值