LeetCode 240: 搜索二维矩阵 II - 算法详解(秒懂系列

文章目录

  • LeetCode 240: 搜索二维矩阵 II - 算法详解
    • 题目描述
    • Java解决方案
    • 算法思路
      • 核心理念
      • 为什么选择右上角?
    • 可视化演示过程
      • 示例1:查找 target = 5
      • 示例2:查找 target = 20 (不存在)
    • 算法分析
      • 时间复杂度
      • 空间复杂度
      • 算法优势
    • 关键要点
    • 扩展思考

LeetCode 240: 搜索二维矩阵 II - 算法详解

题目描述

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列
  • 每列的元素从上到下升序排列

Java解决方案

public class Solution {public boolean searchMatrix(int[][] matrix, int target) {// 从右上角开始搜索int row = 0;int col = matrix[0].length - 1;while (row < matrix.length && col >= 0) {if (matrix[row][col] == target) {return true; // 找到目标值} else if (matrix[row][col] > target) {col--; // 当前值大于目标,向左移动} else {row++; // 当前值小于目标,向下移动}}return false; // 未找到目标值}
}

算法思路

核心理念

利用矩阵的有序特性,从右上角(或左下角)开始搜索,可以在每一步确定性地排除一整行或一整列。

为什么选择右上角?

  • 右上角特性:当前元素是所在行的最大值,同时是所在列的最小值
  • 决策明确
    • 如果当前值 > target,可以排除整列(向左移动)
    • 如果当前值 < target,可以排除整行(向下移动)

可视化演示过程

示例1:查找 target = 5

初始矩阵:

 1  4  7 11 152  5  8 12 193  6  9 16 22
10 13 14 17 24
18 21 23 26 30

搜索过程演示:

步骤当前位置当前值比较结果操作说明
1(0,4)1515 > 5向左移动排除第4列
2(0,3)1111 > 5向左移动排除第3列
3(0,2)77 > 5向左移动排除第2列
4(0,1)44 < 5向下移动排除第0行
5(1,1)55 = 5找到!返回true

步骤可视化:

步骤1: 从右上角开始

 1  4  7 11 [15] ← 起始位置2  5  8 12  193  6  9 16  22
10 13 14 17  24
18 21 23 26  30

步骤2: 向左移动

 1  4  7 [11] ×   ← 15 > 5, 向左移动2  5  8 12  ×3  6  9 16  ×
10 13 14 17  ×
18 21 23 26  ×

步骤3: 继续向左移动

 1  4 [7] ×   ×   ← 11 > 5, 向左移动2  5  8  ×   ×3  6  9  ×   ×
10 13 14  ×   ×
18 21 23  ×   ×

步骤4: 再次向左移动

 1 [4] ×  ×   ×   ← 7 > 5, 向左移动2  5  ×  ×   ×3  6  ×  ×   ×
10 13  ×  ×   ×
18 21  ×  ×   ×

步骤5: 向下移动找到目标

 ×  ×  ×  ×   ×   ← 4 < 5, 向下2 [5] ×  ×   ×   ← 找到目标!3  6  ×  ×   ×
10 13  ×  ×   ×
18 21  ×  ×   ×

示例2:查找 target = 20 (不存在)

搜索过程演示:

步骤当前位置当前值比较结果操作说明
1(0,4)1515 < 20向下移动排除第0行
2(1,4)1919 < 20向下移动排除第1行
3(2,4)2222 > 20向左移动排除第4列
4(2,3)1616 < 20向下移动排除第2行
5(3,3)1717 < 20向下移动排除第3行
6(4,3)2626 > 20向左移动排除第3列
7(4,2)2323 > 20向左移动排除第2列
8(4,1)2121 > 20向左移动排除第1列
9(4,0)1818 < 20向下移动越界,未找到

步骤可视化:

步骤1: 从右上角开始

 1  4  7 11 [15] ← 起始位置,15 < 202  5  8 12  193  6  9 16  22
10 13 14 17  24
18 21 23 26  30

步骤2: 向下移动

 ×  ×  ×  ×   ×   ← 排除第0行2  5  8 12 [19] ← 19 < 20,继续向下3  6  9 16  22
10 13 14 17  24
18 21 23 26  30

步骤3: 继续向下移动

 ×  ×  ×  ×   ×   ← 排除第0行×  ×  ×  ×   ×   ← 排除第1行  3  6  9 16 [22] ← 22 > 20,向左移动
10 13 14 17  24
18 21 23 26  30

步骤4: 向左移动后向下

 ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ← 排除第2行
10 13 14 [17] ×   ← 17 < 20,向下移动
18 21 23  26  ×

步骤5: 继续向下移动

 ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ← 排除第3行
18 21 23 [26] ×   ← 26 > 20,向左移动

步骤6-8: 连续向左移动

步骤6:×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   
18 21 [23] ×  ×   ← 23 > 20,向左步骤7:×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   
18 [21] ×  ×  ×   ← 21 > 20,向左步骤8:×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   
[18] ×  ×  ×  ×   ← 18 < 20,向下

步骤9: 尝试向下移动,越界

 ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ×  ×  ×  ×   ×   ← 所有位置都被排除
[越界] ← row >= matrix.length,搜索结束

最终结果: 返回 false

算法分析

时间复杂度

  • O(m + n) - 其中 m 是行数,n 是列数
  • 最坏情况下需要遍历一行加一列的长度

空间复杂度

  • O(1) - 只使用常量额外空间

算法优势

  1. 高效性:时间复杂度优于暴力搜索O(mn)
  2. 简洁性:代码逻辑清晰,易于理解
  3. 最优性:这是该问题的最优解法之一

关键要点

  1. 起始位置选择:右上角或左下角都可以,但不能选择左上角或右下角
  2. 决策准则:利用有序性质,每步都能排除一行或一列
  3. 边界处理:注意数组越界检查

扩展思考

  1. 为什么不能从左上角开始?

    • 左上角是行最小值和列最小值,无法确定移动方向
  2. 左下角算法

    int row = matrix.length - 1;
    int col = 0;
    // 大于target向上,小于target向右
    
  3. 其他解法对比

    • 每行二分查找:O(m log n)
    • 暴力搜索:O(mn)
    • 右上角搜索:O(m + n) ✓ 最优

这个算法充分利用了矩阵的有序性质,是一个经典的"减治"思想的体现。

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

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

相关文章

洛谷 B4071 [GESP202412 五级] 武器强化

思考难度低&#xff0c;但是代码难度相对较高的题&#xff0c;故做个记录。首先&#xff0c;题目说了要花费最少的钱&#xff0c;所以我们每次拿最便宜的材料给武器1思想&#xff1a;每次都拿最便宜的材料然后考虑一下这个思想是否正确&#xff0c;找一下反例&#xff0c;每次拿…

SQL工具30年演进史:从Oracle到Navicat、DBeaver,再到Web原生SQLynx

目录 一、1990s&#xff1a;厂商自带的数据库工具时代 二、2000s&#xff1a;Navicat等商业数据库管理工具崛起 三、2010s&#xff1a;DBeaver等开源SQL工具兴起 四、2020s&#xff1a;SQLynx&#xff0c;Web原生数据库管理工具 五、SQL工具30年时间线对比 六、总结&…

C语言制作扫雷游戏(拓展版赋源码)

目录 引言&#xff1a; 三个新功能实现 1.可以选择难度或自定义 实现难点解析 代码实现&#xff08;附源码&#xff09; 扫雷.c game.h game.c 2.对选择位置进行标记或取消标记 一.框架 我们先理一下思路 如何构造框架 二.取消标记函数 三.标记函数 四.加入清屏&#xff0c;进…

Python快速入门专业版(十):字符串特殊操作:去除空格、判断类型与编码转换

目录引1.去除空格&#xff1a;清理字符串的实用技巧1.1 三类去空格方法&#xff1a;strip()、lstrip()、rstrip()1.2 实战案例&#xff1a;处理用户输入的空格问题2.判断类型&#xff1a;验证字符串内容的特性2.1 常用类型判断方法2.2 实战案例&#xff1a;验证用户输入的合法性…

Gamma AI:AI演示文稿制作工具,高效解决PPT框架搭建难与排版耗时问题

你做 PPT 的时候是不是也常陷入 “两难”&#xff1f;要么对着空白幻灯片发呆&#xff0c;不知道怎么搭框架 —— 比如要做 “产品季度迭代复盘”&#xff0c;既想放数据又想讲问题&#xff0c;结果页面堆得像乱炖&#xff1b;要么好不容易凑完内容&#xff0c;又花两小时调排版…

【应用案例】AI 给医用过滤器 “找茬”:3 大难点 + 全流程解决方案

【应用案例】AI 给医用过滤器 “找茬”&#xff1a;3 大难点 全流程解决方案&#x1f3af;医用过滤器进行医疗AI检测&#x1f3af;先看痛点&#xff1a;医用过滤器检测难在哪&#xff1f;&#x1f3af;AI检测方案&#xff1a;3步实现“零漏检”1. 硬件定制&#xff1a;让缺陷“…

【数据库相关】TxSQL新增数据库节点步骤

TxSQL新增数据库节点步骤准备工作与注意事项具体操作步骤第 1 步&#xff1a;在主库上创建复制专用账号第 2 步&#xff1a;对主库进行锁表并获取二进制日志坐标第 3 步&#xff1a;备份主库数据并传输到新从库第 4 步&#xff1a;主库解锁第 5 步&#xff1a;在新从库服务器上…

Jmeter快速安装配置全指南

1、JDK安装(Java Development Kit) 1.1.JDK下载 JDK下载址&#xff1a; Java Downloads | Oracle &#xff08;jdk-8u211-windows-x64.exe&#xff09; Android 基于 Java 语言开发&#xff0c;所以必须安装Java环境&#xff0c;Java 环境分JDK 和JRE &#xff0c;JDK提…

设计模式最佳实践 - 模板模式 + 责任链模式

废话不多说&#xff0c;直接切入正题&#xff0c;本篇要讲的是 模板模式 责任链模式 实践。该最佳实践本身就是一种对 责任链模式的增强&#xff0c;模板模式通过 父类 强耦合&#xff0c;预定义好 责任链 next 方法 的前后一些切面行为&#xff0c;优雅简洁。先上示例&#x…

Python快速入门专业版(十一):布尔值与None:Python中的“真假”与“空值”(附逻辑判断案例)

目录引言&#xff1a;为什么“真假”与“空值”是编程的核心逻辑1.布尔值&#xff08;bool&#xff09;&#xff1a;Python中的“真”与“假”1.1 布尔值的基础特性1.2 布尔运算&#xff1a;and、or、not的逻辑规则代码示例&#xff1a;基础布尔运算进阶特性&#xff1a;短路求…

C++学习知识小结

1. 什么是类&#xff1f;什么是对象&#xff1f;两者之间什么关系&#xff1f; 类是一类事物的共同特征的抽象描述&#xff0c;它定义这类所有的属性和方法 可以理解为模版类本身不占用空间&#xff0c;它只是一种定义&#xff0c;描述了对象一个是什么样子、能做什么 对象是根…

9. Mono项目与Unity的关系

1.Mono项目简介 2.Mono项目与Unity是如何结合的 3.从Mono到IL2CPP演变过程1.Mono项目简介 1).定义Mono是一个自由、开源的项目, 由Xamarin现属于微软主导开发; 它的目标是创建一个一套兼容于微软.NET Framework 的跨平台工具2).核心功能a.C#编译器能将你写的C#代码编译成IL(中间…

谷歌Genie 3:让你的照片变成可以玩的游戏世界

你是否曾凝视着一张完美的旅行照片&#xff0c;想象着如果能走进那个画面&#xff0c;自由探索会是怎样一种体验&#xff1f;或者&#xff0c;你是否曾被一幅画的奇幻氛围所吸引&#xff0c;渴望能在那片色彩斑斓的世界里奔跑跳跃&#xff1f;过去&#xff0c;这只是白日梦。而…

Cursor 提示词探索——如何打造真正懂自己的Agent

最近看到鱼皮的Cursor提示词分享&#xff08;微信公众平台)&#xff0c;刚好之前也在做Agent开发&#xff0c;跟提示词打交道的多&#xff0c;也经常发现 ai 蠢蠢的&#xff0c;一点不会根据提示词设计的来&#xff0c;按鱼皮的分享研究了一下&#xff0c;写了这篇博客。 Curs…

C++ 内存模型:用生活中的例子理解并发编程

C 内存模型&#xff1a;用生活中的例子理解并发编程 文章目录C 内存模型&#xff1a;用生活中的例子理解并发编程引言&#xff1a;为什么需要内存模型&#xff1f;核心概念&#xff1a;改动序列原子类型&#xff1a;不可分割的操作内存次序&#xff1a;不同的同步级别1. 宽松次…

AI急速搭建网站:Gemini、Bolt或Jules、GitHub、Cloudflare Pages实战全流程!

文章目录AI急速搭建网站&#xff1a;Gemini、Bolt或Jules、GitHub、Cloudflare Pages实战全流程&#xff01;&#x1f680; 极速建站新范式&#xff1a;Gemini、Bolt.new、GitHub & Cloudflare Pages 全流程实战&#xff01;第一步&#xff1a;创意可视化与代码生成 — Goo…

Qwen2.5-VL实现本地GPTQ量化

本文不生产技术,只做技术的搬运工!! 前言 公开的Qwen2.5-VL模型虽然功能非常强大,但有时面对专业垂直领域的问题往往会出现一些莫名其妙的回复,这时候大家一版选择对模型进行微调,而微调后的模型如果直接部署则显存开销过大,这时就需要执行量化,下面将介绍执行本地GPT…

【Redis】常用数据结构之Hash篇:从常用命令到使用场景详解

目录 1.前言 插播一条消息~ 2.正文 2.1Hash与String对比 2.2常用命令 2.2.1HSET 2.2.2HGET 2.2.3HEXISTS 2.2.4HDEL 2.2.5HKEYS 2.2.6HVALS 2.2.7HGETALL 2.2.8HMGET 2.2.9HLEN 2.2.10HSETNX 2.2.11HINCRBY 2.2.12HINCRBYFLOAT 2.3内部编码 2.3.1. ziplist&…

OSPF基础部分知识点

OSPF基础 前言 路由器 根据 路由表 转发数据包&#xff0c;路由表项 可通过手动配置 和动态路由协议 生成。&#xff08;两种生成方式&#xff09;静态路由比动态路由使用更少的带宽&#xff0c;并且不占用CPU资源来计算和分析路由更新。当网络结构比较简单时&#xff0c;只需配…

Flutter 真 3D 游戏引擎来了,flame_3d 了解一下

在刚刚结束的 FlutterNFriends 大会上&#xff0c;Flame 展示了它们关于 3D 游戏的支持&#xff1a;flame_3d &#xff0c;Flame 是一个以组件系统&#xff08;Flame Component System, FCS&#xff09;、游戏循环、碰撞检测和输入处理为核心的 Flutter 游戏框架&#xff0c;而…