湖南做网站公司如何创建自己的博客
2026/5/13 3:07:02 网站建设 项目流程
湖南做网站公司,如何创建自己的博客,九龙坡区网站建设,wordpress 微信Java版LeetCode热题100之搜索二维矩阵 II#xff1a;从暴力到最优解的完整解析 本文全面剖析 LeetCode 第240题「搜索二维矩阵 II」#xff0c;涵盖题目理解、多种解法实现、复杂度分析、面试技巧及实际应用场景。无论你是准备面试的新手#xff0c;还是希望深入理解算法优化…Java版LeetCode热题100之搜索二维矩阵 II从暴力到最优解的完整解析本文全面剖析 LeetCode 第240题「搜索二维矩阵 II」涵盖题目理解、多种解法实现、复杂度分析、面试技巧及实际应用场景。无论你是准备面试的新手还是希望深入理解算法优化的老手都能从中获得系统性提升。一、原题回顾题目编号LeetCode 240题目名称搜索二维矩阵 IISearch a 2D Matrix II难度等级中等Medium题目描述编写一个高效的算法来搜索m x n矩阵matrix中的一个目标值target。该矩阵具有以下特性每行的元素从左到右升序排列。每列的元素从上到下升序排列。示例示例 1输入 matrix [ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ], target 5 输出true示例 2输入同上 matrixtarget 20 输出false约束条件m matrix.lengthn matrix[i].length1 m, n 300-10⁹ matrix[i][j], target 10⁹每行升序每列升序二、原题分析这道题的关键在于利用矩阵的双重有序性行有序 列有序来设计高效算法。如果我们忽略结构信息直接遍历整个矩阵时间复杂度为 O(mn)虽然能通过测试但显然不是“高效”的体现。题目明确要求“高效算法”暗示我们应利用有序性进行优化。观察矩阵结构行方向从左到右递增 → 可对单行使用二分查找列方向从上到下递增 → 可对单列使用二分查找整体结构并非全局有序如第 i 行末尾可能小于第 i1 行开头因此不能直接对整个矩阵做一次二分但注意右上角或左下角具有特殊性质——它们是所在行的最大值、所在列的最小值或反之这种“临界点”可作为搜索起点实现线性时间复杂度。三、答案构思我们将从最直观到最优化逐步构建三种解法✅ 方法一暴力遍历Brute Force思路双重循环遍历所有元素优点简单直接代码短缺点未利用有序性效率低✅ 方法二逐行二分查找Row-wise Binary Search思路对每一行执行标准二分查找优点利用了行有序性比暴力快缺点未利用列有序性仍有冗余✅ 方法三Z 字形查找Zigzag Search / Staircase Search思路从右上角或左下角出发根据当前值与 target 的大小关系决定移动方向优点充分利用行列双重有序性达到最优时间复杂度 O(m n)缺点思路稍难想到需理解“决策单调性”下面将逐一实现并分析。四、完整答案Java 实现方法一暴力遍历classSolution{publicbooleansearchMatrix(int[][]matrix,inttarget){if(matrixnull||matrix.length0||matrix[0].length0){returnfalse;}for(int[]row:matrix){for(intelement:row){if(elementtarget){returntrue;}}}returnfalse;}}方法二逐行二分查找classSolution{publicbooleansearchMatrix(int[][]matrix,inttarget){if(matrixnull||matrix.length0||matrix[0].length0){returnfalse;}for(int[]row:matrix){if(binarySearch(row,target)){returntrue;}}returnfalse;}privatebooleanbinarySearch(int[]nums,inttarget){intleft0,rightnums.length-1;while(leftright){intmidleft(right-left)/2;// 防止溢出if(nums[mid]target){returntrue;}elseif(nums[mid]target){leftmid1;}else{rightmid-1;}}returnfalse;}} 注意使用left (right - left) / 2而非(left right) / 2是为了防止整数溢出尽管本题数据范围不会溢出但这是良好习惯。方法三Z 字形查找推荐解法classSolution{publicbooleansearchMatrix(int[][]matrix,inttarget){if(matrixnull||matrix.length0||matrix[0].length0){returnfalse;}intmmatrix.length;intnmatrix[0].length;// 从右上角开始(0, n-1)introw0,coln-1;while(rowmcol0){intcurrentmatrix[row][col];if(currenttarget){returntrue;}elseif(currenttarget){// 当前值太大排除当前列因为该列下方都更大col--;}else{// 当前值太小排除当前行因为该行左边都更小row;}}returnfalse;}}✅关键洞察右上角元素是所在行最大、所在列最小若matrix[row][col] target→ 整列都 target → 左移若matrix[row][col] target→ 整行都 target → 下移你也可以从左下角(m-1, 0)开始逻辑对称// 从左下角开始的版本introwm-1,col0;while(row0coln){if(matrix[row][col]target)returntrue;if(matrix[row][col]target){row--;// 太大上移}else{col;// 太小右移}}两种方式均可时间复杂度相同。五、代码分析方法一暴力遍历逻辑清晰两层 for 循环无额外函数边界处理需判断空矩阵适用场景小规模数据或作为 baseline方法二逐行二分模块化设计将二分封装为独立方法提高可读性复用性强binarySearch可用于其他场景性能瓶颈即使某行第一个元素已大于 target仍会继续检查后续行可加剪枝优化优化建议在逐行二分前若matrix[i][0] target可提前终止因为后续行首元素更大。但最坏情况仍为 O(m log n)。方法三Z 字形查找状态机思想每一步只做一次比较决定唯一移动方向无回溯路径单调只向下或向左不会重复访问优雅简洁核心逻辑仅 10 行左右为什么不能从左上角或右下角开始左上角是行最小、列最小 → 无法判断该往右还是往下右下角是行最大、列最大 → 无法判断该往左还是往上只有右上角/左下角具备“一个方向最大、另一个方向最小”的特性才能做出确定性决策。六、时间复杂度和空间复杂度分析方法时间复杂度空间复杂度说明暴力遍历O(m × n)O(1)最坏需检查所有元素逐行二分O(m × log n)O(1)每行二分耗时 O(log n)Z 字形查找O(m n)O(1)每步排除一行或一列最多走 mn 步详细推导Z 字形初始位置(0, n-1)每次操作若target →col--列减少若target →row行增加最多执行n次col--从 n-1 到 -1最多执行m次row从 0 到 m总步数 ≤ m n故时间复杂度为O(m n)性能对比mn300暴力90,000 次比较二分300 × log₂300 ≈ 300 × 9 2,700 次Z 字形最多 600 次Z 字形比二分快约 4.5 倍比暴力快 150 倍七、问题解答FAQQ1为什么 Z 字形查找不会漏掉 target答因为每一步都安全地排除了一整行或一整列。当matrix[x][y] target时由于列有序matrix[x][y]是当前列中最小的在剩余子矩阵中所以整列都 target可安全排除。当matrix[x][y] target时由于行有序matrix[x][y]是当前行中最大的在剩余子矩阵中所以整行都 target可安全排除。这种“排除法”保证了 target 若存在必在剩余区域中。Q2能否从左下角开始效果一样吗答完全可以且逻辑对称。左下角(m-1, 0)行最小、列最大若target → 上移排除当前行若target → 右移排除当前列同样 O(m n)Q3如果矩阵是“蛇形”排列奇数行正序偶数行逆序还能用此方法吗答不能。Z 字形依赖严格的行列单调性。若行方向不一致则无法保证“当前行最大/最小”的性质决策失效。Q4如何扩展到查找 target 的所有位置答Z 字形只能判断存在性。若需找所有位置仍需遍历但可结合剪枝若某行首 target 且行尾 target → 跳过该行或使用哈希表记录已访问位置但空间换时间八、优化思路1. 二分查找的剪枝优化在方法二中可提前终止for(int[]row:matrix){if(row[0]target)break;// 后续行首更大无需检查if(row[row.length-1]target)continue;// 本行最大仍小于 targetif(binarySearch(row,target))returntrue;}但最坏情况target 在最后一行仍为 O(m log n)。2. 分治法高级优化了解即可可将矩阵划分为四象限根据中心值与 target 关系排除部分区域。但实现复杂常数大实际不如 Z 字形。3. 并行化理论可行实际不推荐对多行并行二分但 LeetCode 单线程环境无意义且 overhead 大。✅结论Z 字形查找已是理论最优O(mn)无需进一步优化。九、数据结构与算法基础知识点回顾1. 二分查找Binary Search前提数组有序模板intleft0,rightn-1;while(leftright){intmidleft(right-left)/2;if(arr[mid]target)returnmid;elseif(arr[mid]target)leftmid1;elserightmid-1;}变种查找插入位置、第一个/最后一个等于 target 的位置2. 决策单调性Monotonic Decision在有序结构中某些决策具有“一旦满足条件后续都满足”的性质本题中若某列首元素 target则整列 target → 可跳过3. 矩阵遍历技巧螺旋遍历按圈层遍历对角线遍历按 ij 相同分组Z 字形遍历利用有序性定向移动4. 时间复杂度比较O(1)考察点对问题结构的理解回答左上角元素是所在行和列的最小值。当它小于 target 时我们无法确定 target 在右边还是下边因为两个方向的值都可能更大。这会导致搜索路径不确定可能需要回溯最坏情况退化为 O(mn)。而右上角或左下角具有“一个方向最大、另一个方向最小”的特性能做出确定性决策避免回溯。❓ 面试官如果矩阵很大比如 10⁶ × 10⁶但 target 很小你的算法还高效吗考察点边界情况思考回答Z 字形查找依然高效。例如 target 很小从右上角开始会快速向左移动很快到达第一列然后向下扫描。总步数约为n kk 为 target 所在行仍为 O(m n)。而暴力或二分在大数据下会明显变慢。❓ 面试官能否将此方法推广到三维有序数组考察点知识迁移能力回答理论上可以但复杂度会上升。例如在三维立方体中若每层、每行、每列都有序可从“角点”如 (0,0,n-1)开始每次比较后排除一个面。但时间复杂度可能变为 O(m n p)实现也更复杂。实际中更常用 KD-Tree 或 Octree 等空间索引结构。❓ 面试官如果允许修改矩阵能否预处理以支持 O(1) 查询考察点空间换时间思维回答可以。例如构建哈希集合O(mn) 预处理O(1) 查询但空间 O(mn)构建二维前缀和 二分不适用因非累加结构使用布隆过滤器近似 O(1)但有误判率但在只读场景如本题预处理不可行。十一、这道算法题在实际开发中的应用1. 数据库索引优化二维有序结构类似复合索引如 (age, salary)Z 字形思想可用于范围查询优化快速跳过不满足条件的区块2. 地理信息系统GIS经纬度网格数据常按行列有序存储快速查找某坐标范围内是否存在目标点3. 图像处理灰度图像像素值在局部区域有序快速检测特定亮度值是否存在4. 推荐系统用户-物品评分矩阵经排序后快速判断某用户是否对某类物品打过高分5. 编译器优化符号表常以有序结构存储快速查找变量定义核心价值在大规模有序数据中实现亚线性相对于总数据量的查询效率。十二、相关题目推荐题号题目关联点74. 搜索二维矩阵矩阵全局有序每行末 ≤ 下行首可视为一维数组二分240. 搜索二维矩阵 II本题行列分别有序1351. 统计有序矩阵中的负数同样行列有序可用 Z 字形统计744. 寻找比目标字母大的最小字母循环有序数组二分变种378. 有序矩阵中第 K 小的元素行列有序可用堆或二分答案进阶挑战尝试用 Z 字形思想解决 [1351. 统计负数]时间复杂度 O(m n)。十三、总结与延伸核心收获有序性是优化的关键不要忽视题目给出的结构信息。临界点思维在多重约束下寻找“决策点”如右上角可简化问题。排除法优于穷举每次操作尽可能排除最大无效区域。时间复杂度意识O(mn) 在 m,n≤300 时优势显著。延伸思考若矩阵稀疏大量重复值Z 字形是否仍最优可能出现“平台区”需调整策略如跳过相同值若支持动态插入/删除如何维护有序性需使用平衡树或跳表等动态结构分布式环境下如何并行搜索可将矩阵分块每块独立 Z 字形搜索最终建议面试首选 Z 字形解法简洁、高效、体现算法思维务必手写无 bug注意边界条件空矩阵、单行/单列能讲清原理为什么从右上角为什么不会漏解结语算法之美在于用最简洁的逻辑驾驭复杂的数据结构。搜索二维矩阵 II 不仅是一道题更是培养“结构化思维”的绝佳范例。掌握它你离高效程序员又近了一步

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询