二分查找第一个大于输入的数字的求解
发布日期:2021-05-07 22:01:57 浏览次数:19 分类:精选文章

本文共 2024 字,大约阅读时间需要 6 分钟。

1. 问题描述:

输入:整数n,表示的是数组的大小,整数m表示的是数组的数字的范围,整数k表示的是需要比较的目标数字(数组中的数字按照递增的序列排列的)

2. 题目中数组中的数字是按照递增的顺序排列的,所以我们可以使用二分查找的方法来解决这个问题

在方法中传入整型数组,数组的开始下标,结束下标,需要比较的数字这些变量,当midVal <= n说明我们应该往mid 下标的下一个位置开始寻找第一个大于k的数字,因为数组中的元素是递增的,假如中间的位置的元素小于或者等于说明这个位置以及之前的位置上的数字都是小于等于这个数字k的,所以应该在mid + 1之后的范围去找

int mid = (low + high) >> 1;int midVal = arr[mid];

当中间的位置mid对应的midVal值大于k的时候那么这个时候我们应该在low,mid之间的范围内寻找,这个地方是特别容易出现错误的,因为在二分查找等于从控制台输入的数字的时候我们是从mid + 1的位置去找的,但是这两个问题是不太一样的,对于这个问题我们应该是在low,mid这个范围内去找,可以结合具体的例子来进行验证自己的想法,假如写成了mid那么最终的结果是错误的

例子:

int  k = 9;int arr[] = {1, 5, 5, 5, 7, 8, 8, 9, 10, 10, 10};

假如写成了mid + 1那么最终返回的下标会是8那么结果是错误的,这个过程可以自己根据这个例子来推导一下

可以比较一下使用二分查找求解等于输入的数字的解法

3. 具体的代码如下:

import java.util.Arrays;import java.util.Random;import java.util.Scanner;public class Main{    public static void main(String[] args){        Scanner sc = new Scanner(System.in);        int n = sc.nextInt();        int m = sc.nextInt();        int arr[] = getRandom(n, m);        for(int i = 0; i < n; i++){            System.out.print(arr[i] + " ");        }        int k = sc.nextInt();        System.out.print("\n");        int res = binarySearch(arr, 0, arr.length - 1, k);        System.out.println(res);        sc.close();    }    private static int[] getRandom(int n, int m){        int arr[] = new int[n];        Random rm = new Random();        for(int i = 0; i < n; i++){            arr[i] = rm.nextInt(m) + 1;        }        Arrays.sort(arr);        return arr;    }    private static int binarySearch(int[] arr, int low, int high, int n){        if(low >= high) return low;        int mid = (low + high) >> 1;        int midVal = arr[mid];        if(midVal <= n && low < high){            return binarySearch(arr, mid + 1, high, n);        }else{            //不能写mid + 1否则会出现错误结合具体的例子就知道了            //刚开始的时候调试了很久最后结合具体的例子修改为mid最后结果才是正确的            return binarySearch(arr, low, mid, n);        }        }}

这个程序对于数组中重复元素或者不重复元素都是可以的,因为我们知道假如发现中间下标对应的值是大于输入的数字的时候那么我们这个时候是不应该结束递归的,因为中间位置的这个值我们是不确定它之前有没有比这个数字更小但是有可能大于输入的数字的,所以还应该继续递归下去

上一篇:最长递增子序列的动态规划的求解
下一篇:零一背包的深度优先搜索

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年03月26日 22时26分35秒