需求:比如说查询一个班级大于60分的最低分等等。

思路与二分法基本相同,只不过是对比的逻辑发生了一些小变化,这里所说的上界就是指大于某个值的最小下标。

  • 当mid < target :说明 target 的上界还在mid的右边,所以要去找比mid大的

  • 当mid > target:说明 mid 有可能是target的上界,所以我们加个判断,如果mid前一个元素就刚好是target,说明mid就是我们要找的上界,否则继续找。

另一个注意的点,就是我们取变量 r 的时候,不再是取数组最大的下标了,而是要超过一个,因为如果你找的是数组最后一个元素的上界,其实是不在数组里的。

递归版:

package com.Search;
/**
* @Author: 翰林猿
* @Description: 二分查找upper版(找大于某个值的最小下标)
**/
public class BinarySearchUpper {
   public BinarySearchUpper() {
  }

   public static <E extends Comparable<E>> int SearchUpper(E[] data, E target) {
       return SearchUpper(data, 0, data.length, target);     //是length而不是length-1,因为有可能上界值不在该数组里,所以此时r就应该取大于数组最大值下标+1的位置
  }

   /**
    * @Description 递归版本
    */
   public static <E extends Comparable<E>> int SearchUpper(E[] data, int l, int r, E target) {
       if (l >= r) return -1;
       int mid = l + (r - l) / 2;
       if (data[mid].compareTo(target) <= 0) {         //如果mid小于目标值,说明target的上界还在右边,要去找比mid大的
           return SearchUpper(data, mid + 1, r, target);
      }
       if (data[mid].compareTo(target) > 0 && data[mid - 1].compareTo(target) == 0) {
           return mid;
      }
       //说明mid又大于target,但是mid-1又不等于target,说明当前的mid不是上界。比如说测试用例1, 1, 1, 2, 2, 3, 6, 8, 18, 20
       //我们要找大于3的最小下标也就是6的下标,但是经过两次递归,mid=18,但是18所在的下标为8,8-1=7的元素是8,但是8并不等于3,所以mid=18时不是我们要找的upper
       //此时继续递归
       return SearchUpper(data, l, mid, target);   //mid已经大于目标值了,而且当前的mid不是上界,所以我们往左边找

  }

       public static void main (String[]args){
           Integer[] arr = {1, 1,1, 2, 2, 3, 6, 8, 18, 20};
           int index = SearchUpper(arr, 3);
           System.out.println(index);
      }
  }

非递归版:

package com.Search;
/**
* @Author: 翰林猿
* @Description: 二分查找upper版(找大于某个值的最小下标)
**/
public class BinarySearchUpper {
   public BinarySearchUpper() {
  }

   public static <E extends Comparable<E>> int SearchUpper2(E[] data, E target) {
       return SearchUpper2(data, 0, data.length, target);     //是length而不是length-1,因为有可能上界值不在该数组里,所以此时r就应该取大于数组最大值下标+1的位置
  }
   
   /**
    * @Description 非递归版本
    */
   public static <E extends Comparable<E>> int SearchUpper2(E[] data, int l, int r, E target) {
       while (l < r) {
           int mid = l + (r - l) / 2;
           if (data[mid].compareTo(target) == 0) {
               return mid + 1;
          } else if (data[mid].compareTo(target) > 0) { // 这个r = mid是因为mid的位置可能是目标值
               r = mid;
          } else {
               l = mid + 1;
          }
      }
       // l和r最后都都指向同一个位置。没找到则返回arr.length
       return l;
  }

       public static void main (String[]args){
           Integer[] arr = {1, 1,1, 2, 2, 3, 6, 8, 18, 20};
           int index2 = SearchUpper2(arr, 3);
           System.out.println(index2);
      }
  }

二分查找法upper版(找大于某个值的最小下标)递归+非递归版的更多相关文章

  1. 二分查找法(java版)

    二分查找法也称为折半查找法,在有序的序列中使用二分法可以提高程序的执行效率. 典型的二分查找法代码 public int binarySearch1(int[] arr,int target){ in ...

  2. jvascript 顺序查找和二分查找法

    第一种:顺序查找法 中心思想:和数组中的值逐个比对! /* * 参数说明: * array:传入数组 * findVal:传入需要查找的数 */ function Orderseach(array,f ...

  3. python 全栈开发,Day15(递归函数,二分查找法)

    一.递归函数 江湖上流传这这样一句话叫做:人理解循环,神理解递归.所以你可别小看了递归函数,很多人被拦在大神的门槛外这么多年,就是因为没能领悟递归的真谛. 递归函数:在一个函数里执行再调用这个函数本身 ...

  4. Golang实现二分查找法

    二分查找法就是实现在一组有序的数字数组集合中最快找到指定元素的下标 思路 ①先找到中间的下标middle = (leftIndex + RightIndex) /2 ,然后让中间的下标值和FindVa ...

  5. InnoDB索引概述,二分查找法,平衡二叉树

    索引是应用程序设计和开发的一个重要方面.如果索引太多,应用的性能可能会受到影响:如果索引太少,对查询性能又会产生影响.要找到一个合适的平衡点,这对应用的性能至关重要. 如果知道数据的使用,从一开始就应 ...

  6. 面试官,我会写二分查找法!对,没有 bug 的那种!

    前言科普 第一篇二分搜索论文是 1946 年发表,然而第一个没有 bug 的二分查找法却是在 1962 年才出现,中间用了 16 年的时间. 2019 年的你,在面试的过程中能手写出没有 bug 的二 ...

  7. 选择、冒泡排序,二分查找法以及一些for循环的灵活运用

    import java.util.Arrays;//冒泡排序 public class Test { public static void main(String[] args) { int[] ar ...

  8. 数据机构-折半查找法(二分查找法)-Python实现

    Python实现二分查找法(基于顺序表) class List: elem=[] #存储顺序表元素 last=-1 #设置初始为-1 SeqList = List() #创建一个顺序表 print(& ...

  9. javascript数据结构与算法---检索算法(二分查找法、计算重复次数)

    javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...

  10. php实现二分查找法

    二分查找法需要数组是一个有序的数组 假设我们的数组是一个递增的数组,首先我们需要找到数组的中间位置. 一.要知道中间位置就需要知道起始位置和结束位置,然后取出中间位置的值来和我们的值做对比. 二.如果 ...

随机推荐

  1. hta--Windows运行html的桌面应用程序(HTML应用程序)

    HTA(HTML Application)-- HTML应用程序 作为前端开发,我们能熟练使用html实现各种效果,但是如果要实现一个简单的桌面应用程序那么应该怎么做呢,答案很简单,只需要把html文 ...

  2. 在 Kubernetes 集群上部署 VSCode

    在 Kubernetes 集群上部署 VSCode Visual Studio Code Visual Studio Code 是一个轻量级但功能强大的源代码编辑器,可在您的桌面上运行,适用于 Win ...

  3. python之pdf转换操作 PyMuPDF库学习

    1. 资料链接github地址: pymupdf/PyMuPDF: Python bindings for MuPDF's rendering library官方手册: PyMuPDF Documen ...

  4. ModelAndView方法的返回值类型

    一.ModelAndView @RequestMapping("/selectById") public ModelAndView queryById(Integer id){ M ...

  5. CUDA 的随机数算法 API

    参考自 Nvidia cuRand 官方 API 文档 一.具体使用场景 如下是是在 dropout 优化中手写的 uniform_random 的 Kernel: #include <cuda ...

  6. CentOS 7 部署SonarQube 8.3版本及配置jenkins分析C#代码

    安装SonarQube 8.3版本 官方文档 下载地址 准备工作 准备一台CentOS 7服务器 SonarQube 8.3版本只支持Java 11 (下载Java 11) 安装PostgreSQL ...

  7. 基于APM模式的异步实现及跨线程操作窗体或控件方法的实现示例

    最近在一家某电力外派公司开发相关于GIS的功能,在实现代码的过程中出现了一些常见的问题比如: 1.跨线程执行窗体或控件操作(直接使用委拖) 2.异步模式执行某长时间耗时方法 经过一系列摸索可算找到解决 ...

  8. 2022-11-26:给定一个字符串s,只含有0~9这些字符 你可以使用来自s中的数字,目的是拼出一个最大的回文数 使用数字的个数,不能超过s里含有的个数 比如 : 39878,能拼出的最大回文数是

    2022-11-26:给定一个字符串s,只含有0~9这些字符 你可以使用来自s中的数字,目的是拼出一个最大的回文数 使用数字的个数,不能超过s里含有的个数 比如 : 39878,能拼出的最大回文数是 ...

  9. 2022-06-03:a -> b,代表a在食物链中被b捕食, 给定一个有向无环图,返回这个图中从最初级动物到最顶级捕食者的食物链有几条。 来自理想汽车。

    2022-06-03:a -> b,代表a在食物链中被b捕食, 给定一个有向无环图,返回这个图中从最初级动物到最顶级捕食者的食物链有几条. 来自理想汽车. 答案2022-06-03: 拓扑排序. ...

  10. 2022-04-21:给定一个包含 [0,n) 中不重复整数的黑名单 blacklist, 写一个函数从 [0, n) 中返回一个不在 blacklist 中的随机整数, 对它进行优化使其尽量少调用系

    2022-04-21:给定一个包含 [0,n) 中不重复整数的黑名单 blacklist, 写一个函数从 [0, n) 中返回一个不在 blacklist 中的随机整数, 对它进行优化使其尽量少调用系 ...