【LeetCode 面试经典150题】详细题解之矩阵篇

【LeetCode 面试经典150题】详细题解之矩阵篇

  • 1 矩阵的基础
    • 1.1 表示矩阵
    • 1.2 创建矩阵
    • 相关题目
  • 2 36.有效的数独 (需要复习)
    • 分析
    • 代码
  • 3 54.螺旋矩阵(需要复习)
    • 分析
    • 代码
  • 4 48.旋转图像
    • 思路
    • 代码
  • 5 73.矩阵置零 (一遍过)
    • 5.1 思路
    • 5.2 代码
  • 6 289.生命游戏 (一遍过)
    • 分析
    • 代码

1 矩阵的基础

感觉矩阵的题很简单。迅速过完

12.23 一刷

1.1 表示矩阵

在Java中,矩阵通常可以用二维数组(int[][]double[][]等)来表示。每个内部数组代表矩阵的一行。

int[][] matrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9}
};

1.2 创建矩阵

创建矩阵可以通过直接声明和初始化,或者使用循环动态创建。

int rows = 3;
int columns = 3;
int[][] matrix = new int[rows][columns];
for (int i = 0; i < rows; i++) {for (int j = 0; j < columns; j++) {matrix[i][j] = i * columns + j;}
}

相关题目

36.有效的数独 (看题解做出来,需要复习)

54.螺旋矩阵(做了一次没做对,需要复习

48.旋转图像(一遍过)

73.矩阵置零 (一遍过)

289.生命游戏 (一遍过)

2 36.有效的数独 (需要复习)

36. 有效的数独

中等

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 空白格用 '.' 表示。

示例 1:

img

输入:board = 
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字(1-9)或者 '.'

分析

题目不难。做的时候没想到的是

  1. 没有想到如何判断3*3宫格。(可以用两个坐标来表示9个3*3宫格)
  2. 用数组代替hash表存储该行/该列/该3*3宫格是否出现该数字
        不用完成数独,但是需要判断给出的数独是否是合法数独。核心思想如下:1.每行每列每个九宫格均使用一个hash来存储,以此判断该行该列该九宫格是否出现重复数字具体实现注意以下几点(1)可以使用数组代替hash,每行每列都使用一个大小为9*10的二维数组row[9][10] ,col[9][10]来代表hash表,此外,对于九宫格,则使用一个3*3*10维的,subboard[3][3][10]row[i][num]:代表第i行出现数字num+1的次数col[j][num]:代表第j列出现数字num+1的次数subboard[i][j][num]:代表第[i,j]个九宫格中出现数字 num+1的次数举个例子,board[i][j]=num,那么,可以用row[i][num-1]++,col[j][num-1]++来表示该行该列出现了数字num(2)如何将位置board中的位置映射到对应的九宫格中之前纠结于如何判断属于哪个九宫格,认为一共需要9个数来代表9宫格。看题解后发现可以用两个数来代表九宫格这样一共九个九宫格可以表述如下[0,0] [0,1] [0,2][1,0] [1,1] [1,2][2,0] [2,1] [2,2]与之对应的,举个例子 [0,0]九宫格中的数的i∈[0,2],j∈[0,2] [0,1]:i∈[0,2],j∈[3,5] [0,2]:i∈[0,2],j∈[6,8]可以看到,对于任意坐标(i,j)他会属于[i/3,j/3]九宫格

代码

class Solution {public boolean isValidSudoku(char[][] board) {//1.初始化数组存储每行每列每个九宫格出现的数字int[][] row = new int[9][10];int[][] col = new int[9][10];int[][][] subboard = new int[3][3][10];//2.遍历board中的每个元素for(int i = 0;i<9;i++){for(int j = 0;j<9;j++){if(board[i][j]=='.')continue;//2.1 遍历时,将该元素加入1中初始化的数组中,判断结果是否>1,是的话直接返回falseint num = board[i][j]-'0';row[i][num-1]++;col[j][num-1]++;subboard[i/3][j/3][num-1]++;if(row[i][num-1]>1 || col[j][num-1]>1 || subboard[i/3][j/3][num-1]>1){return false;}}}return true;}}

3 54.螺旋矩阵(需要复习)

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

img

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

img

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

分析

之前做过很多次。但是再做仍然会出现问题。具体是一些细节上的问题。

这次做能够知道3,4需要判断当前行是否遍历过,当前列是否遍历过

但是没有注意到的点为

  1. 举个例子,往右的时候需要初始化当前列,即j=left。就是在往一个方向遍历移动的时候,需要初始化最开始移动的那个下标。

    第一次做的时候,里面的移动用的是for循环,而不是while,所以使用while来遍历的话,就需要在遍历的一开始指定j

                j = left;while(j<right){res.add(matrix[top][j]);j++;num++;}top++;
    
        模拟。用四个指针作为边界,分别为top,bottom,left,right作为上下左右的边界[top,bottom),[left,right)i,j则指向当前元素具体而言1.j<right的时候,往右,到右边界时,top++,往下2.i<bottom的时候,往下,到下边界时,right--,往左3.j>=left的时候,往左,到左边界时,bottom--,往上。4.i>=top的时候,往上,到上边界时,left++,继续重复1-4的步骤注意,34要判断一下,对于3要判断当前行是否遍历过,即判断top<bottom,对于4的话则是判断left<right,满足的话才往左往上遍历

代码

class Solution {public List<Integer> spiralOrder(int[][] matrix) {/***/int top = 0,bottom = matrix.length,left=0,right=matrix[0].length;int num=0;int i=0,j=0;List<Integer> res = new ArrayList<>();while(num<matrix.length*matrix[0].length){j = left;while(j<right){res.add(matrix[top][j]);j++;num++;}top++;i=top;while(i<bottom){res.add(matrix[i][right-1]);i++;num++;}right--;j=right-1;while(top<bottom && j>=left){res.add(matrix[bottom-1][j]);j--;num++;}bottom--;i=bottom-1;while(left<right && i>=top){res.add(matrix[i][left]);i--;num++;}left++;}return res;}
}

4 48.旋转图像

48. 旋转图像

中等

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在** 原地** 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

img

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

img

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

思路

没什么好说的,一遍过。

做过之后就是挺简单的题目

    容易证明先上下翻转之后按照从左上->右下的对角线反转,即为结果

代码

class Solution {public void rotate(int[][] matrix) {/***///1.先上下翻转,matrix[i][j] <->matrix[n-i-1][j]int n = matrix.length;for(int i = 0;i<n/2;i++){for(int j = 0;j<n;j++){int temp = matrix[i][j];matrix[i][j] = matrix[n-i-1][j];matrix[n-i-1][j] = temp;}}//2.按照对角线翻转matrix[i][j] <-> matrix[j][i]for(int i = 0;i<n;i++){for(int j = 0;j<i;j++){int temp = matrix[i][j];matrix[i][j] = matrix[j][i];matrix[j][i] = temp;}}return;}
}

5 73.矩阵置零 (一遍过)

73. 矩阵置零

中等

给定一个 *m* x *n* 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。**

示例 1:

img

输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]

示例 2:

img

输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]

提示:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -231 <= matrix[i][j] <= 231 - 1

进阶:

  • 一个直观的解决方案是使用 O(*m**n*) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(*m* + *n*) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个仅使用常量空间的解决方案吗?

5.1 思路

用了标记数组。

        两个数组标记row[m]:row[i]标记第i行是否出现0col[n]:col[j]标记第j行是否出现01.遍历matrix数字,为row和col两个标记数组赋值,从而得到 每行/每列是否出现0 的结果2.根据row和col两个数组,为原数组赋值

5.2 代码

class Solution {public void setZeroes(int[][] matrix) {/***/int m = matrix.length;int n = matrix[0].length;int[] row = new int[m];int[] col = new int[n];for(int i=0;i<m;i++){for(int j = 0;j<n;j++){if(matrix[i][j]==0){row[i]=1;col[j]=1;}}}for(int i = 0;i<m;i++){if(row[i]==1){for(int j = 0;j<n;j++){matrix[i][j]=0;}}}for(int j = 0;j<n;j++){if(col[j]==1){for(int i=0;i<m;i++){matrix[i][j]=0;}}}return;}
}

6 289.生命游戏 (一遍过)

289. 生命游戏

中等

根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
  3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
  4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是 同时 发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。

给定当前 board 的状态,更新 board 到下一个状态。

注意 你不需要返回任何东西。

示例 1:

img

输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

示例 2:

img

输入:board = [[1,1],[1,0]]
输出:[[1,1],[1,1]]

提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 25
  • board[i][j]01

进阶:

  • 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
  • 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

分析

之前做过有印象。

只要能明白下面的东西就好做了。

    活->死 的细胞,用-1表示死->活 的细胞,用-2表示
        总结一下规则活细胞:当且仅当周围8个位置只有2/3个活细胞的时候,才能活死细胞:当周围8个位置正好有3个活细胞的时候,才能复活假如要原地算法的话,我们在更新细胞的时候,会发现还存在两种状态,即原本是活细胞,现在死了,原本是死细胞,现在活了。这两个状态我们用另外两个数来代表活->死 的细胞,用-1表示死->活 的细胞,用-2表示那么,在第一遍遍历的时候,对活细胞,该细胞周围 状态绝对值为1的细胞个数为23 ,该细胞仍然活着,不更改装填否则,将该细胞状态从1置为-1对死细胞,该细胞周围 状态绝对值为1的细胞个数为3,该细胞死而复生,状态修改为-2第二遍遍历,根据-1-2修改对用的值,-1状态的修改为0,因为死了已经。-2状态的修改为1,因为死细胞活了

代码

class Solution {public void gameOfLife(int[][] board) {/***/int m = board.length;int n = board[0].length;for(int i = 0;i<m;i++){for(int j = 0;j<n;j++){int num = getLifeNum(board,i,j);if(board[i][j]==1 && num!=2 && num!=3){board[i][j]=-1;}else if (board[i][j]==0 && num==3){board[i][j]=-2;}}}for(int i = 0;i<m;i++){for(int j = 0;j<n;j++){if(board[i][j]==-1){board[i][j]=0;}else if(board[i][j]==-2){board[i][j]=1;}}}return;}public int getLifeNum(int[][] board,int x,int y){int m = board.length;int n = board[0].length;int num=0;int[][] dirc = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};for(int i = 0;i<8;i++){if(x+dirc[i][0]>=0 && x+dirc[i][0]<m && y+dirc[i][1]>=0 && y+dirc[i][1]<n && Math.abs(board[x+dirc[i][0]][y+dirc[i][1]])==1){num++;}}return num;}
}

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

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

相关文章

Type-C单口便携显示器LDR6021

Type-C单口便携显示器LDR6021是市场上一种新兴的显示设备&#xff0c;以下是对其的详细介绍&#xff1a; 一、主要特点 便携性&#xff1a;LDR6021采用了Type-C接口作为数据传输和供电接口&#xff0c;这种设计使得它能够与各种支持Type-C接口的设备无缝连接&#xff0c;如笔记…

云途领航:现代应用架构助力企业转型新篇

在数字化转型的浪潮中&#xff0c;现代应用架构为企业带来了灵活性、效率和创新能力。各类服务模型相继出现&#xff0c;为企业提供了强有力的支持&#xff0c;助力其顺利转型。随着技术的快速发展&#xff0c;企业面临的挑战和机遇也在不断演变&#xff0c;这促使它们必须重新…

MyBatis如何处理延迟加载?

大家好&#xff0c;我是锋哥。今天分享关于【MyBatis如何处理延迟加载&#xff1f;】面试题。希望对大家有帮助&#xff1b; MyBatis如何处理延迟加载&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 支持 延迟加载&#xff08;Lazy Loading&am…

C++--------效率和表示

C 效率和表示 效率 时间效率&#xff1a;在 C 中&#xff0c;不同的数据结构和算法有着各异的时间复杂度。例如&#xff0c;访问数组元素的时间复杂度是 O ( 1 ) O(1) O(1)&#xff0c;而遍历链表查找元素的时间复杂度最坏情况下是 O ( n ) O(n) O(n)。选择合适的算法与数据…

apisix的hmac-auth认证

目录 1、apisix的hmac认证Authorization头信息 2、signature的lua生成源码 3、java生成签证的简单示例 4、postman调用如下 apisix的hmac-auth认证&#xff0c;介绍可以看官方文档 hmac-auth | Apache APISIX -- Cloud-Native API Gateway 照着官方文档&#xff0c;发现生…

Java爬虫实战:深度解析VIP商品详情获取技术

在数字化时代&#xff0c;数据的价值不言而喻。对于电商平台而言&#xff0c;掌握VIP商品的详细信息是提升服务质量、优化用户体验的关键。然而&#xff0c;这些信息往往被复杂的网页结构和反爬虫策略所保护。本文将带你深入了解如何使用Java编写爬虫&#xff0c;以安全、高效地…

Kubernetes 常用的网络插件

上篇内容跟大家简单聊了k8s网络模型原理。分别围绕着容器、Pod、Service、网络策略等展开了详细的讲解。这次想跟大家聊聊k8s的CNI网络插件。 CNI 是 Kubernetes 网络模型的核心组件&#xff0c;它是一个插件接口&#xff0c;允许用户选择和配置网络插件来管理 Pod 的网络。CN…

美国站群服务器如何帮助实现有效的多域名管理?

国站群服务器以其丰富的IP资源、高性能硬件和灵活的配置选项&#xff0c;成为多域名管理的理想选择。特别是在需要针对不同域名实现SEO优化、业务分离或多站点运营的场景中&#xff0c;美国站群服务器提供了高效且实用的解决方案。以下是如何利用美国站群服务器实现有效的多域名…

群晖Cloud Sync一键同步让数据管理变得简单

前言&#xff1a;在这个数字化爆炸的时代&#xff0c;数据管理和备份已经变得不可或缺。无论是个人用户还是企业&#xff0c;都需要一种既高效又可靠的方式来管理和备份分散在各种设备和云存储中的文件。而群晖的 **Cloud Sync** 套件正是为了解决这个问题而生。 Cloud Sync 是…

IntelliJ IDEA Docker集成

一、概述 Docker是一种用于在隔离和可复制环境中部署和运行可执行文件的工具。这可能很有用&#xff0c;例如&#xff0c;在与生产相同的环境中测试代码。 IntelliJ IDEA集成了Docker功能&#xff0c;并为创建Docker映像、运行Docker容器、管理Docker Compose应用程序、使用公…

AES 与 SM4 加密算法:深度解析与对比

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

《战神:诸神黄昏》游戏运行时提示mss32.dll丢失怎么办?

《战神&#xff1a;诸神黄昏》游戏运行时提示mss32.dll丢失怎么办&#xff1f; 作为一名软件开发从业者&#xff0c;深知电脑游戏运行时可能会遇到的各种问题&#xff0c;尤其是文件丢失、文件损坏和系统报错等情况。今天&#xff0c;我们就来探讨一下当《战神&#xff1a;诸神…

01.HTTPS的实现原理-HTTPS的概念

01.HTTPS的实现原理-HTTPS的概念 简介1. HTTPS的概念和安全性2. HTTPS的实现原理3. HTTPS和HTTP的区别4. OSI七层协议模型5. SSL和TLS的区别 简介 该系列文章主要讲述了HTTPS协议与HTTP协议的区别&#xff0c;以及HTTPS如何实现安全传输。内容分为三部分&#xff1a;HTTPS的实…

【3DGS文献阅读】Splatter Image: Ultra-Fast Single-View 3D Reconstruction

Splatter Image: Ultra-Fast Single-View 3D Reconstruction 1 背景2 摘要3 简介4 相关工作4.1 单视图的三维重建表示4.2 使用点云进行三维重建4.3 概率三维重建 5 方法6 读文献记录 1 背景 标题&#xff1a;Splatter Image: Ultra-Fast Single-View 3D Reconstruction 溅射图…

PDF书籍《手写调用链监控APM系统-Java版》第7章 插件与链路的结合:Tomcat插件实现

本人阅读了 Skywalking 的大部分核心代码&#xff0c;也了解了相关的文献&#xff0c;对此深有感悟&#xff0c;特此借助巨人的思想自己手动用JAVA语言实现了一个 “调用链监控APM” 系统。本书采用边讲解实现原理边编写代码的方式&#xff0c;看本书时一定要跟着敲代码。 作者…

Intent--组件通信

组件通信1 获取子活动的返回值 创建Activity时实现自动注册&#xff01;【Activity必须要注册才能使用】 默认 LinearLayout 布局&#xff0c;注意 xml 中约束布局的使用&#xff1b; 若需要更改 线性布局 只需要将标签更改为 LinearLayout 即可&#xff0c;记得 设置线性布局…

Unittest02|TestSuite、TestRunner、HTMLTestRunner、处理excel表数据、邮件接收测试结果

目录 八、测试套件TestSuite和测试运行器TestRunner 1、基本概念 2、创建和使用测试套件 3、 自动发现测试用例、创建测试套件、运行测试 4、生成html的测试报告&#xff1a;HTMLTestRunner 1️⃣导入HTMLTestRunner模块 2️⃣运行测试用例并生成html文件 九、unittest…

汽车免拆诊断案例 | 2011 款奔驰 S400L HYBRID 车发动机故障灯异常点亮

故障现象 一辆2011款奔驰 S400L HYBRID 车&#xff0c;搭载272 974发动机和126 V高压电网系统&#xff0c;累计行驶里程约为29万km。车主反映&#xff0c;行驶中发动机故障灯异常点亮。 故障诊断 接车后试车&#xff0c;组合仪表上的发动机故障灯长亮&#xff1b;用故障检测…

【Java 数据结构】面试题 02.02. 返回倒数第 k 个节点

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 题目 2. 解析 2.1 普通方法 2.1 快慢节点方法 3. 代码实现 3.1 普通方法 3.2 快慢节点方法 4. 小结 1. 题目 实现一种算法&#xff0c;找出单向链表…