🔥你好我是fengxin_rou这是我的个人主页 fengxin_rou的主页
❄️欢迎查看我的专栏我的专栏
《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWeb+AI的talis学习系统》、《苍穹外卖》

目录
[二、LeetCode48 旋转图像:n×n 方阵原地顺时针旋转 90° 详解](#二、LeetCode48 旋转图像:n×n 方阵原地顺时针旋转 90° 详解)
[2.1 题目需求与核心难点](#2.1 题目需求与核心难点)
[2.1.1 原题题意回顾](#2.1.1 原题题意回顾)
[2.1.2 解题核心难点](#2.1.2 解题核心难点)
[2.2 数学坐标变换原理推导](#2.2 数学坐标变换原理推导)
[2.2.1 循环边界推导(关键易错点)](#2.2.1 循环边界推导(关键易错点))
[2.3 Java 完整可运行代码实现](#2.3 Java 完整可运行代码实现)
[2.4 第二种解题思路:两次翻转(上下翻转 + 主对角线翻转)拓展方案](#2.4 第二种解题思路:两次翻转(上下翻转 + 主对角线翻转)拓展方案)
[2.5 踩坑总结与面试易错点](#2.5 踩坑总结与面试易错点)
[2.6 拓展延伸:逆时针旋转 90° 变形题思路](#2.6 拓展延伸:逆时针旋转 90° 变形题思路)
[三、LeetCode240 搜索二维矩阵 II:杨氏矩阵高效查找算法详解](#三、LeetCode240 搜索二维矩阵 II:杨氏矩阵高效查找算法详解)
[3.1 题目特性与题意分析](#3.1 题目特性与题意分析)
[3.1.1 矩阵两大关键有序属性](#3.1.1 矩阵两大关键有序属性)
[3.1.2 最优算法切入点:选左下角 / 右上角作为起始坐标](#3.1.2 最优算法切入点:选左下角 / 右上角作为起始坐标)
[3.2 贪心查找算法原理拆解](#3.2 贪心查找算法原理拆解)
[3.3 Java 完整 AC 代码实现](#3.3 Java 完整 AC 代码实现)
[3.4 其他解法拓展:逐行二分查找(进阶对比)](#3.4 其他解法拓展:逐行二分查找(进阶对比))
[3.5 高频踩坑点汇总](#3.5 高频踩坑点汇总)
[3.6 面试拓展提问](#3.6 面试拓展提问)
一、前言
在 Java 后端、算法面试当中,二维矩阵操作是笔试与现场面试高频考点 ,其中 LeetCode 第 48 题《旋转图像(原地顺时针 90° 旋转 n 阶方阵)》、LeetCode 第 240 题《搜索二维矩阵 II(杨氏矩阵查找)》是大厂算法题库经典标杆题目。两道题目分别考察矩阵坐标变换数学规律 与有序数组的二分思想 + 贪心查找,也是数组进阶学习绕不开的核心例题。
本文将从原理推导、解题思路、代码落地、易错踩坑、多种优化方案五个维度,完整拆解两道经典算法题,全部代码基于 Java 实现,可直接粘贴至 LeetCode 在线 OJ 运行通过。
二、LeetCode48 旋转图像:n×n 方阵原地顺时针旋转 90° 详解
2.1 题目需求与核心难点
2.1.1 原题题意回顾
给定大小为n×n的二维整数矩阵,要求原地顺时针旋转 90 度,不允许开辟额外同等大小数组存储结果,只能在原输入矩阵上直接修改元素,空间复杂度约束为\(O(1)\)。 示例输入 3 阶方阵:
1 2 3
4 5 6
7 8 9
顺时针旋转 90° 后输出:
7 4 1
8 5 2
9 6 3
2.1.2 解题核心难点
常规思路:新建数组按映射关系赋值,时间\(O(n^2)\)、空间\(O(n^2)\),违反原地修改的题目硬性限制; 难点 1:推导顺时针 90° 旋转时四个对应位置的坐标数学变换公式; 难点 2:确定双重循环的遍历边界,避免同一个元素被多次轮换、重复修改导致数据错乱; 难点 3:区分奇数阶、偶数阶方阵中心元素处理逻辑(奇数阶矩阵正中心元素旋转后位置不变,无需参与交换)。
2.2 数学坐标变换原理推导
设原矩阵下标[i,j](行 i,列 j,数组下标从 0 开始,矩阵边长 n),顺时针旋转 90° 后,元素会轮换到四个点位:

2.2.1 循环边界推导(关键易错点)
- 外层循环行
i:只需要遍历上半部分行i < n/2,下半行会被上层元素轮换覆盖,重复遍历会二次修改; - 内层循环列
j:奇数阶矩阵中间列不需要遍历,因此j < (n+1)/2,兼容奇偶两种阶数:- n 为偶数:\(n=4,(4+1)/2=2\),j<2,前两列遍历;
- n 为奇数:\(n=3,(3+1)/2=2\),j<2,前两列遍历,中间列 j=2 跳过(中心元素不动)。
2.3 Java 完整可运行代码实现
java
class Solution {
public void rotate(int[][] matrix) {
// 获取方阵阶数n
int n = matrix.length;
// 外层:行边界 i < n/2
for(int i = 0; i < n / 2; i++){
// 内层:列边界 j < (n+1)/2,兼容奇偶阶矩阵
for(int j = 0; j < (n+1) / 2; j++){
// 暂存左上角起始元素
int temp = matrix[i][j];
// 四个点位循环赋值轮换
matrix[i][j] = matrix[n-1-j][i];
matrix[n-1-j][i] = matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j] = matrix[j][n-1-i];
matrix[j][n-1-i] = temp;
}
}
}
}
代码说明:时间复杂度\(O(n^2)\)(每个元素仅被访问 1 次),空间复杂度\(O(1)\),仅使用单个临时变量 temp,完全满足原地修改要求,LeetCode 提交可全用例 AC。
2.4 第二种解题思路:两次翻转(上下翻转 + 主对角线翻转)拓展方案
除四点轮换法外,业界通用另一种原地旋转思路:先上下翻转整行,再沿主对角线翻转,同样满足(O(1))原地要求,附上拓展代码:
java
class SolutionRotate2 {
public void rotate(int[][] matrix) {
int n = matrix.length;
// 第一步:上下行翻转
for(int i = 0; i < n/2; i++){
int[] temp = matrix[i];
matrix[i] = matrix[n-1-i];
matrix[n-1-i] = temp;
}
// 第二步:主对角线(i==j)两侧元素互换
for(int i = 0; i < n; i++){
for(int j = i+1; j < n; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
}

2.5 踩坑总结与面试易错点
- 循环边界写错 :若内层 j 写成
j<n/2,奇数矩阵中间列元素无法参与轮换,结果错误; - 赋值顺序颠倒:四个点位赋值必须倒序,先存起点值,从后往前覆盖,顺序错误直接数据错乱;
- 误区:新手容易直接开辟新数组存储结果,虽然逻辑简单,但违背题目原地核心约束,面试直接扣分;
2.6 拓展延伸:逆时针旋转 90° 变形题思路
逆时针 90° 可修改坐标映射公式,或调整翻转顺序(左右翻转 + 对角线翻转),面试常由原题变形提问。
三、LeetCode240 搜索二维矩阵 II:杨氏矩阵高效查找算法详解
3.1 题目特性与题意分析
3.1.1 矩阵两大关键有序属性
-
每行元素:从左到右严格升序;
-
每列元素:从上到下严格升序 ; 该类有序矩阵也被称作杨氏矩阵(Young tableau),要求在\(O(m+n)\)最优时间复杂度内查找目标 target,禁止暴力全遍历\(O(mn)\)。 样例矩阵:
1 4 7 11 15
2 5 8 12 19
3 6 9 16 22
10 13 14 17 24
查找 target=5 返回 true,查找 target=20 返回 false。 【此处插入杨氏矩阵查找起点(左下角)标注示意图,箭头标注移动规则】
3.1.2 最优算法切入点:选左下角 / 右上角作为起始坐标
- 左下角特点:本行最大、本列最小 ;
- 当前值 < target:本列全部小于 target,列右移
j++; - 当前值 > target:本行全部大于 target,行上移
i--;
- 当前值 < target:本列全部小于 target,列右移
- 同理右上角(本行最小、本列最大)也可作为起点,移动逻辑反向。
3.2 贪心查找算法原理拆解
起始坐标:i = m-1(最后一行下标),j=0(首列下标),循环终止条件:行越上界 (i<0) 或列越右界 (j>= 总列数):
matrix[i][j] < target:当前整列所有元素≤当前值,目标不可能在本列,列 + 1;matrix[i][j] > target:当前整行所有元素≥当前值,目标不可能在本行,行 - 1;- 相等直接返回 true;循环结束未命中返回 false。
3.3 Java 完整 AC 代码实现
java
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
// 边界特判:空矩阵直接返回false
if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
return false;
}
// 起点:左下角坐标,最后一行、第0列
int i = matrix.length - 1;
int j = 0;
// 循环:坐标不出矩阵边界
while(i >= 0 && j < matrix[0].length){
if(matrix[i][j] < target){
// 偏小→右移一列
j++;
}else if(matrix[i][j] > target){
// 偏大→上移一行
i--;
}else{
// 找到目标值
return true;
}
}
// 遍历结束未找到
return false;
}
}
复杂度:时间\(O(m+n)\)(行、列最多各走一次),空间\(O(1)\),最优解,LeetCode 全部测试用例通过。
3.4 其他解法拓展:逐行二分查找(进阶对比)
由于每行有序,可对每行单独二分查找,时间复杂度\(O(m*logn)\),数据量极大时效率低于贪心\(O(m+n)\),附上二分版本代码:
java
class SolutionSearchBinary {
public boolean searchMatrix(int[][] matrix, int target) {
for(int[] row : matrix){
// 单行二分
int left = 0, right = row.length -1;
while(left <= right){
int mid = left + (right - left)/2;
if(row[mid] == target) return true;
else if(row[mid] < target) left = mid +1;
else right = mid -1;
}
}
return false;
}
}
3.5 高频踩坑点汇总
- 空数组边界遗漏 :未判断
matrix[0].length==0,输入空行数组会触发数组下标越界异常; - 起始坐标选错:从左上角 (0,0) 开始无法贪心移动,只能暴力遍历,算法直接退化;
- 移动方向搞反:小于 target 时错误行下移,大于 target 错误列左移,逻辑完全失效。
3.6 面试拓展提问
面试官延伸:杨氏矩阵查找第 K 小元素,基于本题思路衍生堆解法,是进阶面试考点。
四、两道题目面试横向对比总结
| 题目 | 核心思想 | 最优时空复杂度 | 考察侧重点 |
|---|---|---|---|
| 48. 旋转矩阵 | 坐标数学变换 / 矩阵翻转 | \(O(n^2)、O(1)\) | 二维数组下标规律、原地操作思维 |
| 240. 杨氏查找 | 贪心 + 有序特性 | \(O(m+n)、O(1)\) | 有序数据的贪心策略、边界处理 |
【此处插入两张题目考点思维导图汇总图片占位】
五、算法学习优化拓展与资源推荐
- 刷题平台官方文档 LeetCode 官方中文题库文档:https://leetcode.cn/problemset/all/,可在线调试两道原题,查看官方题解与多语言实现方案;
- 算法开源仓库 Java 算法刷题开源库(Github):https://github.com/doocs/leetcode,收录全 LeetCode 题解、多思路优化版本,适合日常查漏补缺。
学习建议:先手动在草稿纸上模拟坐标变换与查找移动步骤,再落地编码,切忌直接复制代码,吃透下标规律才能应对各类矩阵变形面试题。
六、结语
矩阵类算法是数组从一维进阶二维的关键分水岭,两道经典题分别代表坐标变换 与有序贪心两大算法方向,也是校招、社招后端算法笔试常客。吃透本文推导逻辑与代码,后续遇到矩阵转置、矩阵螺旋遍历、杨氏矩阵变种题均可快速举一反三。
如果本篇内容对你的算法学习有帮助,欢迎点赞 + 收藏,后续持续更新 LeetCode 高频数组、链表、二叉树面试真题详解~

