LeetCode 热题 100 | 矩阵

embedded/2025/1/19 13:31:04/

矩阵基础

  • 使用哈希数组来标记当前行或者列是否出现0
  • 按层模拟
  • 旋转90度可以先水平翻,然后再对角线翻

73. 矩阵置零

题目讲解:LeetCode
重点:

  1. 使用标记数组:用两个标记数组分别记录每一行和每一列是否有零出现。
  2. 使用两个标记变量:用矩阵的第一行和第一列代替两个标记数组。再额外使用两个标记变量分别记录第一行和第一列是否原本包含 0。

思路:

  • 使用标记数组
    1.首先遍历该数组一次,如果某个元素为 0,那么就将该元素所在的行和列所对应标记数组的位置置为 true。
    2.最后我们再次遍历该数组,用标记数组更新原数组即可。
  • 使用两个标记变量
    1.首先预处理出两个标记变量,接着使用其他行与列去处理第一行与第一列。
    2.然后反过来使用第一行与第一列去更新其他行与列,最后使用两个标记变量更新第一行与第一列即可。

复杂度:

  • m 是矩阵的行数,n 是矩阵的列数
  • 使用标记数组
    时间复杂度:O(mn)
    空间复杂度:O(m+n)
  • 使用两个标记变量
    时间复杂度:O(mn)
    空间复杂度:O(1)
// 使用标记数组
public void setZeroes(int[][] matrix) {// 重点: 用两个标记数组分别记录每一行和每一列是否有零出现boolean[] row = new boolean[matrix.length];boolean[] col = new boolean[matrix[0].length];for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {if (matrix[i][j] == 0) {row[i] = true;col[j] = true;}}}for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {if (row[i] || col[j]) matrix[i][j] = 0;}}
}
// 使用两个标记变量
public void setZeroes(int[][] matrix) {boolean row0Flag = false;boolean col0Flag = false;for (int j = 0; j < matrix[0].length; j++) {if (matrix[0][j] == 0) {row0Flag = true;break;}}for (int i = 0; i < matrix.length; i++) {if (matrix[i][0] == 0) {col0Flag = true;break;}}// 重点: 使用第一行和第一列标记for (int i = 1; i < matrix.length; i++) {for (int j = 1; j < matrix[0].length; j++) {if (matrix[i][j] == 0) {matrix[0][j] = 0;matrix[i][0] = 0;}}}for (int i = 1; i < matrix.length; i++) {for (int j = 1; j < matrix[0].length; j++) {if (matrix[0][j] == 0 || matrix[i][0] == 0) {matrix[i][j] = 0;}}}// 重点: 再用两个标记变量处理第一行和第一列if (row0Flag) {Arrays.fill(matrix[0], 0);}if (col0Flag) {for (int i = 0; i < matrix.length; i++) matrix[i][0] = 0;}
}

54. 螺旋矩阵

题目讲解:LeetCode
重点:

  1. 按层模拟。四个标记。

思路:

  • 按层模拟
    1.每一层遍历 顶 右 底 左。每遍历完一个对应的边界需要处理。

复杂度:

  • m 和 n 分别是行数和列数
  • 时间复杂度:O(mn)。每个元素都要被访问一次。
  • 空间复杂度:O(1)。除了输出数组以外,空间复杂度是常数。
public List<Integer> spiralOrder(int[][] matrix) {List<Integer> result = new ArrayList<>();int curTop = 0;int curRight = matrix[0].length - 1;int curBottom = matrix.length - 1;int curLeft = 0;// 重点: 按层模拟, 每一层遍历 顶 右 底 左while (curLeft <= curRight && curTop <= curBottom) {// 当前层的最顶行for (int i = curLeft; i <= curRight; i++) {result.add(matrix[curTop][i]);}curTop++;// 当前层的最右列for (int i = curTop; i <= curBottom; i++) {result.add(matrix[i][curRight]);}curRight--;// 当前外层的最底行还存在if (curTop <= curBottom) {for (int i = curRight; i >= curLeft; i--) {result.add(matrix[curBottom][i]);}}curBottom--;// 当前外层的最左列还存在if (curLeft <= curRight) {for (int i = curBottom; i >= curTop; i--) {result.add(matrix[i][curLeft]);}}curLeft++;}return result;
}

48. 旋转图像

题目讲解:LeetCode
重点:

  1. 原地旋转代码背下来。
  2. 用翻转代替旋转。水平翻,然后对角线翻。

思路:

  • 原地旋转
  1. 逆时间的顺序来替换。背下来。
  • 用翻转代替旋转
  1. 先水平翻转
  2. 再对角线翻转

复杂度:

  • N 是 matrix 的边长
  • 原地旋转
    时间复杂度:O(N^2)
    空间复杂度:O(1)
  • 用翻转代替旋转
    时间复杂度:O(N^2)
    空间复杂度:O(1)
// 原地旋转
public void rotate(int[][] matrix) {int n = matrix.length;// 替换一半另一半就相当于自动替换过去了for (int i = 0; i < n / 2; i++) {// 内层要加一是因为n为奇数时需要多遍历一遍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;}}
}
// 用翻转代替旋转
public void rotate(int[][] matrix) {int n = matrix.length;// 重点: 先水平翻转for (int i = 0; i < matrix.length / 2; i++) {for (int j = 0; j < matrix[0].length; j++) {int temp = matrix[i][j];matrix[i][j] = matrix[n - i - 1][j];matrix[n - i - 1][j] = temp;}}// 重点: 再对角线翻转, 循环条件看作楼梯, 外层循环i=0则为对角线左侧楼梯顶层for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < i; j++) {int temp = matrix[i][j];matrix[i][j] = matrix[j][i];matrix[j][i] = temp;}}
}

题目讲解:LeetCode
重点:
1.

思路:
1.

复杂度:

  • 时间复杂度:
  • 空间复杂度:


http://www.ppmy.cn/embedded/155230.html

相关文章

Kaggle欺诈检测:使用生成对抗网络(GAN)解决正负样本极度不平衡问题

### Kaggle欺诈检测&#xff1a;使用生成对抗网络&#xff08;GAN&#xff09;解决正负样本极度不平衡问题 #### 引言 在金融领域中&#xff0c;欺诈检测是一项至关重要的任务。然而&#xff0c;欺诈交易数据往往呈现出正负样本极度不平衡的特点&#xff0c;这给机器学习模型…

leetcode 407. 接雨水 II

题目&#xff1a;407. 接雨水 II - 力扣&#xff08;LeetCode&#xff09; 堆bfs。 模拟水流出去的过程。先把边缘的单元都加到堆里&#xff0c;从堆顶最小的单元开始bfs&#xff0c;遍历到的单元的四周&#xff0c;都会从该单元流出去&#xff0c;四周的单元的剩余水量高度m…

【RK3588嵌入式图形编程】-SDL2-创建应用窗口

创建应用窗口 文章目录 创建应用窗口1、认识SDL及安装1.1 什么是SDL1.2 SDL安装2、应用程序准备3、应用程序实现3.1 创建窗口3.2 Window类3.3 Surface3.4 SDL_FillRect3.5 颜色和SDL_MapRGB()3.6 SDL_UpdateWindowSurface3.7 SDL_DestroyWindow()3.8 main函数4、总结SDL2是一个…

业务架构、数据架构、应用架构和技术架构

TOGAF(The Open Group Architecture Framework)是一个广泛应用的企业架构框架&#xff0c;旨在帮助组织高效地进行架构设计和管理。 TOGAF 的核心就是由我们熟知的四大架构领域组成:业务架构、数据架构、应用架构和技术架构。 企业数字化架构设计中的最常见要素是4A 架构。 4…

stm32控制直流电机程序

在STM32微控制器上控制直流电机通常涉及使用PWM&#xff08;脉宽调制&#xff09;信号来调节电机的速度&#xff0c;并通过GPIO&#xff08;通用输入输出&#xff09;端口来控制电机的启动、停止和方向。以下是一个简化的STM32控制直流电机的程序示例&#xff0c;该程序使用STM…

指针的进阶

指针的主题&#xff0c;我们在初级阶段的《指针》章节已经接触过了&#xff0c;我们知道了指针的概念&#xff1a; 1. 指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 2. 指针的大小是固定的4/8个字节&#xff08;32位平台/64位平台&#xff0…

Spring Boot 实战:轻松实现文件上传与下载功能

目录 一、引言 二、Spring Boot 文件上传基础 &#xff08;一&#xff09;依赖引入 &#xff08;二&#xff09;配置文件设置 &#xff08;三&#xff09;文件上传接口编写 &#xff08;一&#xff09;文件类型限制 &#xff08;二&#xff09;文件大小验证 &#xff0…

【Java回顾】Day7 Java IO|分类(传输方式,数据操作)|零拷贝和NIO

# Java IO 知识体系 IO-分类(传输&#xff0c;操作) 传输方式 字节流 字符流 字节流和字符流的区别 字节流读取单个字节&#xff0c;字符流读取单个字符字节流来处理二进制文件(图片&#xff0c;MP3&#xff0c;视频文件)&#xff0c;字符流(文本文件(特殊的二进制文件&a…