leetcode 之 二分查找(java)(2)

news2025/4/19 9:11:54

文章目录

    • 74、搜索二维矩阵
    • 33、搜素旋转排序数组

74、搜索二维矩阵

题目描述

给你一个满足下述两条属性的 m x n 整数矩阵:

  • 每行中的整数从左到右按非严格递增顺序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false

示例 1:

img

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true

示例 2:

img

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • -104 <= matrix[i][j], target <= 104

思路

首先,题目要求查询target是否在矩阵中,同时矩阵是有序存储的,从左到右,从上到下增大,即右下 > 左上。

target的状态:

情况一、 target在矩阵外,即小于矩阵最小值,大于矩阵最大值。

情况二、target处于矩阵范围内,同时是矩阵内元素,返回true。

情况三、target处于矩阵范围内,但不是矩阵内元素,返回false。

思路:①、我们先遍历矩阵的行,确认target所处的范围是在哪一行,使用idx记录。

​ ②、我们对该行使用二分法,求出target的具体位置。

二分具体实现:

方法1

  • 我们使用全开区间,即(l, r) 表示范围,

  • 令 l = -1, r = n,即恰好在矩阵长度左右范围 + 1,因为是开区间,不包含l和r本身。

  • 同时在循环中加入判断 if(r - l <= 1) break; 因为要判断target恰好在两个数之间,不是矩阵元素的情况。

代码如下:

题解:

	//方法1
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        
        if(target < matrix[0][0] || target > matrix[m - 1][n - 1]) return false;
        int idx = 0;

        for(int i = 0; i < m; i ++ ) {
            if(matrix[i][n - 1] < target) continue;
            else if(matrix[i][n - 1] >= target) {
                idx = i;
                break;
            }
        }
        // 左开右开区间()
        int l = -1, r = n;
        boolean flag = false;
        while(l < r) {
            int mid = (l + r) / 2;
            if(matrix[idx][mid] > target) r = mid;
            else if(matrix[idx][mid] < target) l = mid;
            else {
                flag = true;
                break;
            }
            if(r - l <= 1) break;
        }
        return flag;
    }

方法2

  • 使用我们使用全闭区间,即[l, r] 表示区间范围。

  • 令l = 0, r = n - 1。因为是闭区间,我们需要包含l和r本身。

  • 闭区间不需要添加判断,因为l和r有 + 1和 - 1的权值变化,最终会自己跳出循环。

代码如下:

int l = 0, r = n - 1;
boolean flag = false;
while(l <= r) {
    int mid = (l + r) / 2;
    if(matrix[idx][mid] > target) r = mid - 1;
    else if(matrix[idx][mid] < target) l = mid + 1;
    else {
        flag = true;
        break;
    }
}
return flag;

33、搜素旋转排序数组

问题描述

整数数组 nums 按升序排列,数组中的值 互不相同

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2]

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

示例 2:

输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例 3:

输入:nums = [1], target = 0
输出:-1

提示:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -104 <= target <= 104

思路:

  • 就以[4, 5, 6, 7, 0, 1, 2], target = 8 举例

我们可以明显的看出,如果想要使用二分,就需要找有序的数组,此时我们看到,

  • 该数组有两段局部有序的数组。

  • nums[0]一定大于第二段有序数组的所有数。

我们可以根据第二条性质,使得每次判断都是在有序数组中。

  • 我们实现二分的判断依据就成了,target是否在当前有序数组中,如果不在,那么肯定在该有序数组右(左)边

最开始判断,相等,就直接返回mid.

然后,判断if(nums[0] <= nums[mid])。

  • 这样规定的mid一定处于第一段有序数组中,
    • 内部继续判断if(nums[0] <= target && target < nums[mid]) r = mid - 1
    • else 说明target位于更右边 l = mid + 1

其次,else中

  • 这样的mid一定处于第二段有序数组中,
    • 判断if(nums[mid] < target && target <= nums[n - 1]) l = mid + 1;
    • else 说明target位于更左边 r = mid - 1;

题解

public int search(int[] nums, int target) {
    if(nums.length == 1) return (nums[0] == target) ? 0 : -1;
    int n = nums.length;
    int l = 0, r = n - 1;

    while(l <= r) {
        int mid = (l + r) / 2;
        if(nums[mid] == target) return mid;
        if(nums[0] <= nums[mid]) {
            if(nums[0] <= target && target < nums[mid]) r = mid - 1;
            else l = mid + 1;
        } else {
            if(nums[mid] < target && target <= nums[n - 1]) l = mid + 1;
            else r = mid - 1;
        }
    }
    return -1;
}

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

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

相关文章

16asm - 汇编介绍 和 debug使用

文章目录 前言硬件运行机制微机系统硬件组成计算机系统组成8086cpu组织架构dosbox安装配置debug debug使用R命令D命令E命令U命令T命令A命令标志寄存器 总结 前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解 十六位汇编 和 debug调试器的使用 硬件运行…

UE4_材质节点_有关距离的_流体模拟

一、材质节点介绍&#xff1a; 特别注意&#xff1a;距离场需要独立显卡支持。 1、什么是距离场&#xff1f; 想象一下空间中只有两个实体, 一个球,一个圆柱. 空间由无数个点组成, 取其中任何一个点, 比如,它跟球面的最近距离是3, 跟圆柱面的最近距离是2, 那么这个点的值就…

win10系统安装docker-desktop

1、开启Hyper-v ———————————————— Hyper-V 是微软提供的一种虚拟化技术&#xff0c;它允许你在同一台物理计算机上运行多个独立的操作系统实例。这种技术主要用于开发、测试、以及服务器虚拟化等领域。 —————————————————————— &#…

【小白学机器学习39】如何用numpy生成总体,生成样本samples

目录 1 目的&#xff1a;研究 样本和总体之间的关系 2 先生成1个理论总体 2.0 下面是关于这一步的完整代码 2.1 一般情况下&#xff0c;我们先生成一个符合正态分布的总体 2.1.1 设置总体 &#xff0c;或者说生成一个总体 2.2 为什么一定要是一个符合正态分布的总体&…

“指标管理系统”是什么?企业如何搭建指标管理系统?

在当今数字化时代&#xff0c;数据已成为企业决策的重要依据。然而&#xff0c;海量数据中如何筛选出关键指标&#xff0c;并对其进行有效管理&#xff0c;成为了众多企业面临的难题。为此&#xff0c;指标管理系统应运而生&#xff0c;它旨在帮助企业规范化定义、统一管理和高…

网际协议(IP)与其三大配套协议(ARP、ICMP、IGMP)

网际协议&#xff08;Internet Protocol&#xff0c;IP&#xff09;&#xff0c;又称互联网协议。是OSI中的网络层通信协议&#xff0c;用于跨网络边界分组交换。它的路由功能实现了互联互通&#xff0c;并从本质上建立了互联网。网际协议IP是 TCP/IP 体系中两个最主要的协议之…

运维工作常用Shell脚本(Commonly Used Shell Scripts for Operation and Maintenance Work)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

机器学习8-决策树CART原理与GBDT原理

Gini 系数 和Gini 系数增益 CART决策树算法流程举例 该篇文章对于CART的算法举例讲解&#xff0c;一看就懂。 决策树(Decision Tree)—CART算法 同时也可以观看视频 分类树 GBDT原理举例 可以看如下示例可以理解GBDT的计算原理 用通俗易懂的方式讲解&#xff1a; GBDT算法及…

oracle中删除指定前缀的表

近期接手做的项目&#xff0c;发觉数据库中有许多多余的表。究其原因&#xff0c;应该是同事贪图方便&#xff0c;将过去做过的项目复制粘贴&#xff0c;然后修修改改。包括数据库也是克隆过来的&#xff0c;然后又没有删除本项目多余的表&#xff0c;结果经过几个轮回&#xf…

JAVA篇10 —— 常用类WrapperStringMathArraysSystemBigIntegerBigDecimal日期

欢迎来到我的主页&#xff1a;【一只认真写代码的程序猿】 本篇文章收录于专栏【小小爪哇】 如果这篇文章对你有帮助&#xff0c;希望点赞收藏加关注啦~ 目录 1 包装类 1.1 包装类和String 1.2 int&char包装类常用方法 2 String类 3 Math 类 4 Arrays类 5 System类…

tauri使用github action打包编译多个平台arm架构和inter架构包踩坑记录

这些error的坑&#xff0c;肯定是很多人不想看到的&#xff0c;我的开源软件PakePlus是使用tauri开发的&#xff0c;PakePlus是一个界面化将任何网站打包为轻量级跨平台软件的程序&#xff0c;利用Tauri轻松构建轻量级多端桌面应用和多端手机应用&#xff0c;为了实现发布的时候…

通义灵码走进北京大学创新课堂丨阿里云云原生 10 月产品月报

云原生月度动态 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 趋势热点 &#x1f947; 通义灵码走进北京大学创新课堂&#xff0c;与 400…

鸿蒙开发-HMS Kit能力集(地图服务、华为支付服务)

地图服务 Map Kit&#xff08;地图服务&#xff09;是鸿蒙生态下的一个地图服务&#xff0c;为开发者提供强大而便捷的地图能力&#xff0c;助力全球开发者实现个性化地图呈现、地图搜索和路线规划等功能&#xff0c;轻松完成地图构建工作。 Map Kit提供了千万级别的 Poi&…

【四轴】基于IIC通信读写MPU6050寄存器

1. 基本原理 在这篇【四轴】软件IIC通信的实现 – Dukis Blog博客中&#xff0c;我介绍了软件IIC的实现方式。而MPU6050&#xff0c;正是一种通过IIC进行通信的传感器外设。 1.1 什么是MPU6050 MPU6050 是 InvenSense 公司推出的一款6 轴惯性传感器模块&#xff0c;广泛应用于姿…

arkTS:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)

arkUI&#xff1a;使用ArkUI实现用户信息的持久化管理与自动填充&#xff08;PersistentStorage&#xff09; 1 主要内容说明2 例子2.1 登录页2.1.1登陆页的相关说明2.1.1.1 持久化存储的初始化2.1.1.2 输入框2.1.1.3 记住密码选项2.1.1.4 登录按钮的逻辑2.1.1.5 注册跳转 2.1.…

基于SpringBoot+Vue的美妆购物网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【SpringBoot+Vue】x-admin管理系统跟做

技术栈 前端技术说明Vue前端框架Vuex全局状态管理框架ElementUI前端UI框架Axios前端HTTP框架vue-element-admin项目脚手架 后端技术说明SpringBoot容器MVC框架MyBatisORM框架MyBatis-plusMyBatis增强工具Redis非关系型数据库 数据库准备 SET NAMES utf8mb4; SET FOREIGN_KE…

【Docker】Docker配置远程访问

配置Docker的远程访问&#xff0c;你需要按照以下步骤进行操作&#xff1a; 1. 在Docker宿主机上配置Docker守护进程监听TCP端口 Docker守护进程默认只监听UNIX套接字&#xff0c;要实现远程访问&#xff0c;需要修改配置以监听TCP端口。 ‌方法一&#xff1a;修改Docker服务…

LeetCode hot100(自用背诵、部分题目、非最优解)

点击题目可以跳转到LeetCode 哈希 两数之和 public int[] twoSum(int[] nums, int target) {int lengthnums.length;int[] ans new int[2];for (int i 0; i <length-1 ; i) {for (int j i1; j < length; j) {if(nums[i]nums[j]target){ans[0]i;ans[1]j;}}}return an…

Android -- 简易音乐播放器

Android – 简易音乐播放器 播放器功能&#xff1a;* 1. 播放模式&#xff1a;单曲、列表循环、列表随机&#xff1b;* 2. 后台播放&#xff08;单例模式&#xff09;&#xff1b;* 3. 多位置同步状态回调&#xff1b;处理模块&#xff1a;* 1. 提取文件信息&#xff1a;音频文…