【力扣hot100】二分查找

news2024/10/6 2:21:47

文章目录

    • Arrays.sort()时间复杂度o(n)
    • 二分法时间复杂度o(logn)
  • 1.搜索插入位置
      • 代码
  • 2. 搜索二维矩阵
      • 思路:
      • 代码:
  • 34. 在排序数组中查找元素的第一个和最后一个位置
      • 思路:
      • 代码:
  • 153. 寻找旋转排序数组中的最小值
      • 思路:
      • 代码:
  • 81.搜索旋转排序数组
      • 思路:
      • 代码
  • 4. 寻找两个正序数组的中位数[hard]
    • 思路:还没看,不会做

Arrays.sort()时间复杂度o(n)

二分法时间复杂度o(logn)

1.搜索插入位置

在这里插入图片描述

代码

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                return mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
}

2. 搜索二维矩阵

在这里插入图片描述

思路:

由于每行的第一个元素大于前一行的最后一个元素,且每行元素是升序的,所以每行的第一个元素大于前一行的第一个元素,因此矩阵第一列的元素是升序的。

我们可以对矩阵的第一列的元素二分查找找到最后一个不大于目标值的元素,然后在该元素所在行中二分查找目标值是否存在。
先查找行,再查找列。

代码:

注意:需要判断列是否越界

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int left=0;
        int right=matrix.length-1;
        // 第一次二分查找,先查找行
        while(left<=right){
            int mid=left+(right-left)/2;
            if(matrix[mid][0]==target){
                return true;
            }else if(matrix[mid][0]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        int row=right;//获取到元素所在的行
        if(row<0)return false;
        //当元素在第一行也没有查找到时,row是left(0)的前一个,这个时候数组index会报错,所以提前进行判断
        left=0;
        right=matrix[0].length-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(matrix[row][mid]==target){
                return true;
            }else if(matrix[row][mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return false;
    }
}

34. 在排序数组中查找元素的第一个和最后一个位置

在这里插入图片描述

思路:

先找左边界,再找右边界。通过条件判断是否为边界,
注意:返回一个数组,则使用new int[] {1,2}的形式

代码:

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int num1=searchLeft(nums,target);
        int num2=searchRight(nums,target);
        // return [num1,num2];
        return new int[] {num1,num2};
    }
    public int searchLeft(int[] nums, int target){
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                if(mid==0||nums[mid]!=nums[mid-1]){
                    return mid;
                }else{
                    right=mid-1;
                }
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return -1;
    }
    public int searchRight(int[] nums, int target){
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                if(mid==nums.length-1||nums[mid]!=nums[mid+1]){
                    return mid;
                }else{
                    left=mid+1;
                }
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return -1;
    }
}

153. 寻找旋转排序数组中的最小值

在这里插入图片描述

思路:

注意:在考虑选取最后一个点进行判断时,包含了顺序的情况,但是移动太诡异了,我不考虑。
而在选取第一个点进行临界值判断时,如果有顺序的情况会越界,所以先判断是不是按顺序,再跟第一个点比较。
p=nums[0],当nums[mid]数值比p大时,说明在旋转点的左边,也就是最小值的左边,所以直接将左指针转移到mid的右边,去考虑右边的区间。
当nums[mid]数值<=p时,说明在旋转点的右边,也就是最小值的右边,所以直接将左指针转移到mid的右边,去考虑右边的区间。

代码:

class Solution {
    public int findMin(int[] nums) {
        // Arrays.sort(nums); O(nlogn)
        // return nums[0];
        
        //二分法
        int left=0,right=nums.length-1;
        //如果没有旋转,第一个数就是最小的
        if(nums[left]<=nums[right]){
            return nums[left];
        }
        int p=nums[0];// 将临界点设置为数组的第一个值
        while(left<=right){
            // System.out.println("b-right"+right);
            // System.out.println("b-left"+left);
            int mid=left+(right-left)/2;
            if(nums[mid]<p){
                right=mid-1;
            }else if(nums[mid]>=p){
                left=mid+1;
            }
        }//旋转点是right
        //则要找到的值就是旋转点的后一个,left
        return nums[left];
    }
}

81.搜索旋转排序数组

在这里插入图片描述

思路:

这道题其实是要我们明确「二分」的本质是什么。

「二分」不是单纯指从有序数组中快速找某个数,这只是「二分」的一个应用。

「二分」的本质是两段性,并非单调性。只要一段满足某个性质,另外一段不满足某个性质,就可以用「二分」。

经过旋转的数组,显然前半段满足 >= nums[0],而后半段不满足 >= nums[0]。我们可以以此作为依据,通过「二分」找到旋转点。
在这里插入图片描述
先找旋转点。再根据target和nums[0]的取值判断是在0-旋转点 还是旋转点+1到末尾之间。

代码

class Solution {
    public int search(int[] nums, int target) {
        //先找旋转点
        int n=nums.length-1;
        int left=0,right=n;
        int p=nums[0];
        // if(nums[left]<=nums[right])//说明是顺序数组
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]<p){
                right=mid-1;
            }else{
                left=mid+1;
            }
            System.out.println(left); //左侧
        }
        //则旋转点就是left-1(right)
    //重新计算left right值
        if(target>=p){
            left=0;
        }else{
            // l=left;
            right=n;
        }
        //第二次二分
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]>target){
                right=mid-1;
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

4. 寻找两个正序数组的中位数[hard]

在这里插入图片描述

思路:还没看,不会做

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1400605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.2 基于深度学习和先验状态的实时指纹室内定位

文献来源 Nabati M, Ghorashi S A. A real-time fingerprint-based indoor positioning using deep learning and preceding states[J]. Expert Systems with Applications, 2023, 213: 118889.&#xff08;5.2_基于指纹的实时室内定位&#xff0c;使用深度学习和前一状态&…

从零开始的OpenGL光栅化渲染器构建3-法线贴图和视差贴图

前言 我们可以用一张纹理贴图来表现物体表面的基础反射颜色&#xff0c;也可以用一张镜面反射贴图&#xff0c;来指派表面是否产生高光。除此之外&#xff0c;我们可以用贴图来存储表面的法线信息&#xff0c;以及高度信息&#xff0c;从而让渲染效果更加精细。 法线贴图 我…

linux下USB抓包和分析流程

linux下USB抓包和分析流程 在windows下抓取usb包时可以通过wireshark安装时安装USBpcap来实现usb抓包&#xff0c;linux下如何操作呢&#xff1f; 是基于usbmon&#xff0c;本博客简单描述基于usbmon在linux系统上对通过usb口进行发送和接收的数据的抓包流程&#xff0c;分别描…

Matplotlib Mastery: 从基础到高级的数据可视化指南【第30篇—python:数据可视化】

文章目录 Matplotlib: 强大的数据可视化工具1. 基础1.1 安装Matplotlib1.2 创建第一个简单的图表1.3 图表的基本组件&#xff1a;标题、轴标签、图例 2. 常见图表类型2.1 折线图2.2 散点图2.3 条形图2.4 直方图 3. 图表样式与定制3.1 颜色、线型、标记的定制3.2 背景样式与颜色…

Linux:使用for+find查找文件并cp到其他目录,文件名带有空格

一、场景描述 在终端窗口中&#xff0c;用shell命令&#xff0c;批量拷贝文件到指定目录。 我是在Windows系统上&#xff0c;通过git bash终端来执行shell命令的。 二、实现过程 命令1 for filepath in find /d/LearningMaterials/数学/数学/高中/一数/偏基础&#xff08;基…

Zabbix分布式监控系统概述、部署、自定义监控项、邮件告警

目录 前言 &#xff08;一&#xff09;业务架构 &#xff08;二&#xff09;运维架构 一、Zabbix分布式监控平台 &#xff08;一&#xff09;Zabbix概述 &#xff08;二&#xff09;Zabbix监控原理 &#xff08;三&#xff09;Zabbix 6.0 新特性 1. Zabbix server高可用…

用BEVformer来卷自动驾驶-4

书接前文 前文链接&#xff1a;用BEVformer来卷自动驾驶-3 (qq.com) 上文书介绍了BEVformer是个啥&#xff0c;以及怎么实现Deformable-attention 我们继续 BEVformer的输入数据格式&#xff1a; 输入张量&#xff08;batachsize&#xff0c;queue&#xff0c;cam&#xff0c;…

工厂设计模式看这一篇就够了

本文将重点介绍几种工厂设计模式&#xff1a;简单工厂、工厂方法模式、抽象工厂模式和建造者模式。这几种设计模式在生产制造的流程下层层递进&#xff0c;可以满足不同的使用场景。在实际运用时&#xff0c;没有一个万能的工厂模式可以套用&#xff0c;要结合具体业务场景选择…

【华为GAUSS数据库】IDEA连接GAUSS数据库方法

背景&#xff1a;数据库为华为gauss for opengauss 集中式数据库 IDEA提供了丰富的各类型数据库驱动&#xff0c;但暂未提供Gauss数据库。可以通过以下方法进行连接。 连接后&#xff0c; 可以自动检查xml文件中的sql语句是否准确&#xff0c;表名和字段名是否正确还可以直接在…

基于 IoT 物联网 + 5G 技术搭建 100万台电梯智能化运维平台

随着近20年我国房地产的蓬勃发展&#xff0c;电梯已经成为人们现代生活中不可或缺的一部分&#xff0c;也是城市化建设中重要的建筑设备之一。据中国电梯行业协会统计&#xff0c;截至2022年底&#xff0c;我国电梯保有量为990万台&#xff0c;电梯运营健康度&#xff0c;减少事…

Pyro —— Sparse vs dense simulations

目录 Simulation area Sparse solving Understanding resizing Simulation area 在模拟的期间&#xff0c;pyro场都在当前容器内定义&#xff1b;开始非常小&#xff0c;随模拟的进行&#xff0c;解算器会不断的对其扩展或收缩&#xff1b;为重置流体框&#xff0c;解算器会…

Android 基础技术——addView 流程

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于 addView 在了解 addView 流程之前&#xff0c;先回答下以下几个问题&#xff1a; PhoneWindow是什么时候创建的&#xff1f; DectorView 是什么&#xff1f; DectorView 是什么时候创建的&#xf…

conda国内加速

1、配置国内源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ 2、显示源地址 conda config --set show_channel_urls yes

外呼机器人有什么优势?

外呼机器人有什么优势&#xff1f;值得受到大多数电销企业的追捧&#xff01; 1、电话外呼效率高&#xff1a; 每天可拨打的电话数量是人工的5-10倍&#xff0c;人工一天只能拨打200-300通电话&#xff0c;机器人每天能打3000通电话以上&#xff0c;无须休息&#xff0c;按照…

PWM之舵机

舵机又称直流电机&#xff0c;如下图 本节承接上节&#xff0c;具体的PWM技术已经在上一节讲的很详细了&#xff0c;本节就不再讲了&#xff0c;那么我们的重点就放在直流电机的工作原理上了。 一、工作原理 我们研究直流电机&#xff0c;主要式研究直流电机旋转速度的调节&a…

linux LPT和COM回路测试(基于python+Qt+C++)

软件UI: 回路治具&#xff08;COMLPT&#xff09;&#xff1a; lpt_test.cpp&#xff08;c 源代码&#xff09;&#xff1a; #include <iostream> #include <fstream> #include <sstream> #include <unistd.h> #include <fcntl.h> #include <…

什么是游戏盾?哪家效果好。

游戏盾是什么呢&#xff0c;很多做游戏开发的客户估计都是听说过的&#xff0c;但是也不是所有的游戏开发者会运用到。因为&#xff0c;游戏盾是针对游戏行业APP业务所推出的高度可定制的网络安全管理解决方案&#xff0c;除了能针对大型DDoS攻击(T级别)进行有效防御外&#xf…

Python(18)--文件输入/输出 Ⅱ

​ 大家好&#xff01;我是码银&#x1f970; 欢迎关注&#x1f970;&#xff1a; CSDN&#xff1a;码银 公众号&#xff1a;码银学编程 前言 前一篇文章&#xff08;python(17)–文件的输入/输出-CSDN博客&#xff09;介绍了如何操作文本文件和二进制文件&#xff0c;以及对应…

设计亚马逊按销售排名功能

1&#xff1a; 定义 Use Cases 和 约束 Use cases 作用域内的Use Case Service 通过目录计算过去一周内最受欢迎的产品User 通过目录去View过去周内最受欢迎的产品Service 有高可用 作用域外 整个电商网站 设计组件&#xff08;只是计算销售排名&#xff09; 约束和假设…

【Python】模块

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…