首页 > 其他分享 >3.二分搜索

3.二分搜索

时间:2024-03-17 15:58:07浏览次数:16  
标签:二分 target nums int 索引 length 搜索 数组

定义

Step1:计算数据的中点索引值m = (i+j)/2 向下取整 。i为首元素索引,j为尾元素索引。
Step2:判断 nums[m] 和target 的大小关系,分为以下三种情况。

  1. 当 nums[m] < target 时,说明 target 在区间中:
    i = m + 1
  2. 当 nums[m] > target 时,说明 target 在区间中:
    j = m -1
  3. 当 nums[m] = target 时,说明找到 target ,返回索引m 。

具体应用场景

1)在有序数组中确定num存在还是不存在

//查找是需保证nums[]为有序的
    public static int binarySearch(int[] nums, int target) {
        if (nums == null || nums.length == 0) {  //如果是空则返回-1
            return -1;
        }
        int i = 0,j = nums.length-1,m = -1; //i为数组首元素索引,j为数组尾元素索引,m为中点索引
            while (i<=j){
                m = (i + j)/2;
                if (nums[m] == target){
                    return m;
                } else if (nums[m] > target) {//2. 当nums[m] > target时,说明target在区间中:j = m -1
                     j = m-1;
                }else {//1. 当nums[m] < target时,说明target在区间中:i = m + 1
                    i = m+1;
                }
            }
        return -1;//没有找到target,返回-1
    }

2)在有序数组中找≥=target的最左位置

  //在有序数组中找>=target的最左位置,需要nums[]有序
    public static int findLeft(int nums[],int target){
        int ans = -1;//返回值,初始化为-1,找到符合要求的值n后改为n的索引值,没有找到就为-1
        int i = 0, j = nums.length-1,m = 0;
        while (i<=j){
            m = (i + j)/2;
            if (nums[m] >= target){//如果nums[i]>=target
                ans = m;//更新ans的值为nums[i]的索引ji
                j = m-1;//调整右边界索引
            }else {
                i = m+1;//如果nums[i]<target,则nums[i]左侧位置都比target小,所以调整二分等我左边界
            }
        }
        return ans;
    }
}

3)在有序数组中找<=target的最右位置

   //查找在有序数组中找<=target的最右位置
    public static int findRight(int nums[], int target) {
        int ans = -1;//返回值,初始化,为-1,找到符合要求的值n后改为n的索引值,没有找到就为-1
        int i = 0, j = nums.length - 1, m = 0;//i为左边界索引,j为右边界索引,m为重点索引
        while (i <= j) {
            m = (i + j) / 2;
            if (nums[m] <= target) { //如果nums[m]<=target,证明nums[m]左侧位置都小于target
                ans = m;//更新ans的值
                i = m + 1;//更新左边界
            } else {//如果nums[m]>m.证明小于target的值在m位置的左侧
                j = m - 1;//更新右边界
            }
        }
        return ans;
    }

4)二分搜索不一定发生在有序数组上(比如寻找峰值问题)

//查找峰值问题,nums[]不要求有序
    /**
     * 峰值元素是指其值严格大于左右相邻值的元素
     * 给你一个整数数组 nums,已知任何两个相邻的值都不相等
     * 找到峰值元素并返回其索引
     * 数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
     * 假设 nums[-1] = nums[n] = 无穷小
     */
    public static int findPeakElement(int nums[]) {
        if (nums.length == 0) {//如果是空数组则返回1;
            return -1;
        }
        if (nums.length == 1) {//如果数组长度为1.怎nums[0]就是峰值点
            return 0;
        }
        if (nums[0] > nums[1]) {
            return 0;
        }
        if (nums[nums.length - 1] > nums[nums.length - 2]) {
            return nums.length - 1;
        }
        int l = 1, r = nums.length - 2, ans = -1;//上面if语句判断过0和n-位置是否为峰值点,所以如果不是就更新左右边界为1和n-2
        while (l <= r) {
            int m = (l + r) / 2;
            if (nums[m] < nums[m - 1]) {//数组最左边界为上升,若m位置小于m-1位置,则m~m-1位置为开口向下的二次函数,则在这段区间存在峰值。
                r = m - 1;//更新右边界为中点左侧
            } else if (nums[m] < nums[m + 1]) {//数组最右边界为下降,若m位置小于m+1位置,则m~m+1位置为开口向下的二次函数,则在这段区间存在峰值。
                l = m + 1;//更新左边界为中点右侧
            } else {//如果m位置大于m-1和m+1位置,则m位置为峰值
                ans = m;
                break;
            }
        }
        return ans;
    }

5)“二分答案法”这个非常重要的算法,左神后续讲解

测试链接 : https://leetcode.cn/problems/find-peak-element/

标签:二分,target,nums,int,索引,length,搜索,数组
From: https://blog.csdn.net/ccccslt/article/details/136749347

相关文章

  • 【c语言练习之二分查找】
    二分查找二分查找的前提二分查找必须是在一个整形的有序数组中实现二分查找的思想对于一个整形的有序数组,输入一个你想要查找的数key,将key与数组的中间元素mid作比较,使得数组被分成2部分,要查找的数key肯定在某一部分,这样就可以舍弃另一部分,在另一部分中继续用这种思......
  • 【喜大普奔】Dynamo节点搜索功能官方终于优化了
    Hello大家好!我是九哥~用Dynamo的小伙伴,一直都在诟病其检索功能的拉胯,每次搜个节点都是一卡一卡的,好不容易搜完了,还不是自己想要的结果,奈何官方却迟迟没见动作。早先时候,在群里分享过一个节点包:Monocle,装了以后呢,可以使用第三方的搜索栏,效果是杠杠的啊,速度特别快。但是,有......
  • 【洛谷 P8602】[蓝桥杯 2013 省 A] 大臣的旅费 题解(图论+深度优先搜索+树的直径+链式
    [蓝桥杯2013省A]大臣的旅费题目描述很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同......
  • 代码随想录 第22天 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入
    leetcode:701.二叉搜索树中的插入操作-力扣(LeetCode)classSolution{publicTreeNodeinsertIntoBST(TreeNoderoot,intval){//判断叶子结点,null说明到了,可以赋值。if(root==null){TreeNodenode=newTreeNode(val);return......
  • 专题 | 二分&0/1分数规划&数学期望
    二分二分编号对于一个有单调性的数组,我们可以二分编号,如果a[mid]<ans,那么mid就往a[]更大的那边走while(r>l){mid=(l+r)/2;if(judge(mid))l=mid;elser=mid;}注意二分代码的写法细节和你的check函数有关!(其实是和你在对于恰好满足要求时check返回值有......
  • LeetCode题练习与总结:搜索插入位置
    一、题目给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为O(logn)的算法。二、解题思路初始化两个指针,left指向数组的起始位置,right指向数组的结束位置。当left小于等......
  • 二分/二分查找(整数二分详解+拓展浮点二分)
    先上题目在一个有序数组中,查找x所在的下标。输入第一行两个整数n和m。第二行n个数,表示有序的数列。接下来m行,每行一个整数x,表示一个询问的数。输出对于每个询问如果x在数列中,输出下标。否则输出-1样例输入15334579738输出141-1提示对于100%的数......
  • win10 运行搜索的历史记录 记不下来
    win10系统,运行窗口中总是不记录使用过的命令,每次都要重新输入一遍很麻烦,我们一起看看,怎么解决这个问题。工具/原料win10方法/步骤 在电脑左下角winows图标,在弹出的快捷菜单中选择“设置” 弹出的windows设置窗口,选择“隐私” ......
  • 搜索与回溯算法
    排列#include<cstdio>#include<iostream>#include<algorithm>#include<iomanip>intvis[25],ans[25];intn;usingnamespacestd;voiddfs(intdep){if(dep==n+1){for(inti=1;i<=n;i++)cout<<setw(......
  • 分布式搜索elasticsearch(1)
    1.初识elasticsearch1.1.了解ES1.1.1.elasticsearch的作用elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容例如:在GitHub搜索代码在电商网站搜索商品 在百度搜索答案在打车软件搜索附近的车1.1.2.ELK技......