当前位置: 首页 > news >正文

力扣top100(day01-05)--矩阵

73. 矩阵置零

class Solution {public void setZeroes(int[][] matrix) {int length=matrix.length;int wingth=matrix[0].length;// 使用集合记录需要置零的行和列Set<Integer> n = new HashSet<>();Set<Integer> m = new HashSet<>();for(int i=0;i<length;i++){for(int j=0;j<wingth;j++){if(matrix[i][j]==0){n.add(i);m.add(j);}}} for(int l:n){for(int k=0;k<wingth;k++){matrix[l][k]=0;}}for(int g:m){for(int h=0;h<length;h++){matrix[h][g]=0;}}}
}

代码解读:矩阵置零(Set Matrix Zeroes)

这段代码实现了将矩阵中所有0元素所在的行和列全部置为0的功能。以下是详细解析:


1. 核心思路
  • 问题要求:给定一个m×n的矩阵,如果某个元素为0,则将其所在行和列的所有元素都设为0。

  • 解决方法:使用两个HashSet分别记录需要置零的行和列索引,然后统一处理。


2. 代码解析
(1) 初始化行列集合

java

Set<Integer> n = new HashSet<>();  // 存储需要置零的行索引
Set<Integer> m = new HashSet<>();  // 存储需要置零的列索引
  • n:记录包含0元素的行号

  • m:记录包含0元素的列号

(2) 第一次遍历:标记0的位置

java

for(int i=0;i<length;i++){for(int j=0;j<wingth;j++){if(matrix[i][j]==0){n.add(i);  // 记录行号m.add(j);  // 记录列号}}
}
  • 遍历整个矩阵,发现0时记录其行列索引。

(3) 行置零处理

java

for(int l:n){for(int k=0;k<wingth;k++){matrix[l][k]=0;  // 将整行置零}
}
  • 遍历所有标记行,将该行所有元素设为0。

(4) 列置零处理

java

for(int g:m){for(int h=0;h<length;h++){matrix[h][g]=0;  // 将整列置零}
}
  • 遍历所有标记列,将该列所有元素设为0。


3. 复杂度分析
  • 时间复杂度:O(m×n),需要遍历矩阵两次(标记+置零)

  • 空间复杂度:O(m+n),最坏情况下需要存储所有行和列索引


4. 示例演示

输入矩阵

text

[[1, 1, 1],[1, 0, 1],[1, 1, 1]
]

执行过程

  1. 发现0在(1,1),记录行1和列1

  2. 将第1行全部置零:[1,0,1]→[0,0,0]

  3. 将第1列全部置零:

    • [1][0]→0

    • [2][0]→0(实际值不变)

  4. 输出

text

[[1,0,1],[0,0,0],[1,0,1]
]

54. 螺旋矩阵

class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> order = new ArrayList<Integer>();if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return order;}int rows = matrix.length, columns = matrix[0].length;int left = 0, right = columns - 1;int top = 0, bottom = rows - 1;while (left <= right && top <= bottom) {// 1. 从左到右遍历上层for (int column = left; column <= right; column++) {order.add(matrix[top][column]);}// 2. 从上到下遍历右列for (int row = top + 1; row <= bottom; row++) {order.add(matrix[row][right]);}// 3. 从右到左遍历下层(确保不是单行)if (left < right && top < bottom) {for (int column = right - 1; column > left; column--) {order.add(matrix[bottom][column]);}// 4. 从下到上遍历左列(确保不是单列)for (int row = bottom; row > top; row--) {order.add(matrix[row][left]);}}// 边界收缩left++; right--; top++; bottom--;}return order;}
}

代码解读:螺旋矩阵(Spiral Matrix)

这段代码实现了按顺时针螺旋顺序遍历二维矩阵的功能。以下是详细解析:


1. 核心思路
  • 问题要求:将矩阵元素按从外到内顺时针顺序排列。

  • 解决方法:使用边界收缩法,通过四个边界指针(left, right, top, bottom)逐步向内层遍历。


2. 代码解析
(1) 初始化边界指针

java

int left = 0, right = columns - 1;  // 左右边界(列)
int top = 0, bottom = rows - 1;     // 上下边界(行)
  • left/right控制列范围,top/bottom控制行范围。

(2) 螺旋遍历

java

while (left <= right && top <= bottom) {// 1. 从左到右遍历上层for (int column = left; column <= right; column++) {order.add(matrix[top][column]);}// 2. 从上到下遍历右列for (int row = top + 1; row <= bottom; row++) {order.add(matrix[row][right]);}// 3. 从右到左遍历下层(确保不是单行)if (left < right && top < bottom) {for (int column = right - 1; column > left; column--) {order.add(matrix[bottom][column]);}// 4. 从下到上遍历左列(确保不是单列)for (int row = bottom; row > top; row--) {order.add(matrix[row][left]);}}// 边界收缩left++; right--; top++; bottom--;
}

遍历顺序

  1.  左到右(上层)

  2.  上到下(右列)

  3.  右到左(下层,需判断非单行)

  4.  下到上(左列,需判断非单列)

(3) 边界收缩

每次完成一圈遍历后,四个边界同时向内收缩:

java

left++;   // 左边界右移
right--;  // 右边界左移
top++;    // 上边界下移
bottom--; // 下边界上移

3. 示例演示

输入矩阵

text

[[1, 2, 3],[4, 5, 6],[7, 8, 9]
]

执行过程

  1. 第一圈:

    • → 1→2→3

    • ↓ 6→9

    • ← 8→7

    • ↑ 4

    • 边界收缩:left=1, right=1, top=1, bottom=1

  2. 第二圈:

    • → 5

    • 边界收缩结束

  3. 输出[1,2,3,6,9,8,7,4,5]


4. 复杂度分析
  • 时间复杂度:O(m×n),每个元素被访问一次

  • 空间复杂度:O(1)(不考虑输出列表)


5. 关键点总结
  1. 边界条件

    • 检查top < bottomleft < right避免重复遍历单行/列

    • 空矩阵直接返回

  2. 遍历顺序

    • 必须遵循→↓←↑的严格顺序

  3. 终止条件

    • left > righttop > bottom时结束循环

48. 旋转图像

class Solution {public void rotate(int[][] matrix) {int n = matrix.length;for (int i = 0; i < n / 2; ++i) {for (int j = 0; j < (n + 1) / 2; ++j) {int temp = matrix[i][j];matrix[i][j] = matrix[n - j - 1][i];matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];matrix[j][n - i - 1] = temp;}}}
}

代码解读:螺旋矩阵(Spiral Matrix)

1. 获取矩阵维度

java

int n = matrix.length;
  • 作用:获取n×n矩阵的边长

  • 示例:3×3矩阵 → n=3

2. 外层循环:控制旋转层数

java

for (int i = 0; i < n / 2; ++i) {
  • 含义

    • n / 2:矩阵需要旋转的层数(如4×4矩阵有2层)

    • i:当前处理的层数索引(从外到内)

  • 示例

    • 4×4矩阵:i取值0,1(两层)

    • 3×3矩阵:i取值0(一层,中心点不动)

3. 内层循环:处理当前层元素

java

for (int j = 0; j < (n + 1) / 2; ++j) {
  • 含义

    • (n + 1) / 2:处理奇偶矩阵差异

    • j:当前层元素的列索引

  • 设计原因

    • 奇数矩阵:中间列不需要处理(如3×3矩阵的j取值0,1)

    • 偶数矩阵:全部列都需要处理

4. 四元素轮换核心逻辑

java

int temp = matrix[i][j];
matrix[i][j] = matrix[n - j - 1][i];
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
matrix[j][n - i - 1] = temp;

分步解析(以3×3矩阵的(0,0)点为例):

  1. 保存左上角

    java

    int temp = matrix[0][0]; // temp = 1
  2. 左下 → 左上

    java

    matrix[0][0] = matrix[2][0]; // 1 ← 7
  3. 右下 → 左下

    java

    matrix[2][0] = matrix[2][2]; // 7 ← 9
  4. 右上 → 右下

    java

    matrix[2][2] = matrix[0][2]; // 9 ← 3
  5. temp → 右上

    java

    matrix[0][2] = temp; // 3 ← 1

坐标变换规律

位置坐标变换公式示例(3×3)
左上(i,j)(0,0)
左下(n-j-1,i)(2,0)
右下(n-i-1,n-j-1)(2,2)
右上(j,n-i-1)(0,2)
5. 边界处理细节
  • 奇数矩阵中心点

    • n为奇数时,(n + 1) / 2确保中心点不被处理

    • 例如3×3矩阵的中心点(1,1)不会被遍历到

6. 时间复杂度分析
  • O(n²):每个元素被访问一次

  • 空间复杂度O(1):仅使用temp临时变量

7. 示例完整流程

输入矩阵

text

[[1, 2, 3],[4, 5, 6],[7, 8, 9]
]

旋转步骤

  1. 外层(0,0)点开始:

    • 四角交换:1←7←9←3←1

    • 边中交换:2←4←8←6←2

  2. 结果:

text

[[7, 4, 1],[8, 5, 2],[9, 6, 3]
]
8. 关键设计思想
  1. 分层处理:将矩阵看作洋葱,逐层剥离

  2. 四元组交换:每组4个位置同时旋转

  3. 坐标映射:通过数学计算确定旋转后的位置

  4. 奇偶兼容(n+1)/2的统一处理

9. 常见误区提醒
  1. 边界错误

    • 错误:使用j < n / 2会漏掉奇数列

    • 正确:必须用(n + 1) / 2

  2. 交换顺序

    • 必须逆时针或顺时针统一方向

  3. 中心点处理

    • 奇数矩阵中心点无需旋转

240. 搜索二维矩阵 II

class Solution {public boolean searchMatrix(int[][] matrix, int target) {for (int[] row : matrix) {for (int element : row) {if (element == target) {return true;}}}return false;}
}
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m = matrix.length, n = matrix[0].length;int x = 0, y = n - 1;while (x < m && y >= 0) {if (matrix[x][y] == target) {return true;}if (matrix[x][y] > target) {--y;} else {++x;}}return false;}
}

http://www.lryc.cn/news/619085.html

相关文章:

  • Golang 语言中 Context 的使用方式
  • 【Python 爬虫】Playwright 多浏览器支持(Chromium/Firefox/WebKit)
  • 云原生高级——nginx
  • Nginx 高级配置
  • 明远智睿T113-i核心板:工业设备制造的“破局者”
  • 10-docker基于dockerfile自动制作镜像
  • 机器学习——DBSCAN
  • imx6ull-驱动开发篇20——linux互斥体实验
  • [TryHackMe]Relevant(smb+windows令牌提权)
  • HarmonyOS元服务开发系列教程(三):实现音乐播放和封面旋转
  • 【问题解决】从Anaconda环境迁移到miniforge并在IDEA中完成环境配置
  • 【数据分享】2020-2022年我国乡镇的逐日最高气温数据(Shp/Excel格式)
  • C++动态代理技术详解:实现原理与应用场景
  • beacon-dongle系统(二)AP及Server建立
  • 双十一美妆数据分析:洞察消费趋势与行业秘密
  • 电商双 11 美妆数据分析学习报告
  • MyBatis持久层实现
  • 【前端Vue】log-viewer组件的使用技巧
  • Qwen-Image(阿里通义千问)技术浅析(一)
  • 物联网、大数据与云计算持续发展,楼宇自控系统应用日益广泛
  • [Robotics_py] 路径规划算法 | 启发式函数 | A*算法
  • Linux系统编程Day13 -- 程序地址空间
  • Seata深度剖析:微服务分布式事务解决方案
  • 微服务ETCD服务注册和发现
  • 力扣经典算法篇-50-单词规律(双哈希结构+正反向求解)
  • SQL 合并两个时间段的销售数据:FULL OUTER JOIN + COALESCE
  • 杰里平台7083G 如何支持4M flash
  • 【K8s】K8s控制器——复制集和deployment
  • 【SpringBoot】08 容器功能 - SpringBoot底层注解汇总大全
  • 4.运算符