LeetCode刷题笔记2——数组2

重塑数组

题目

在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

示例

示例 1:

输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]

示例 2:

输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]

提示:

m == mat.length
n == mat[i].length
1 <= m, n <= 100
-1000 <= mat[i][j】 <= 1000
1 <= r, c <= 300

二维数组的一维表示

对于一个行数为 m,列数为 n,行列下标都从 00开始编号的二维数组,我们可以通过下面的方式,将其中的每个元素 (i, j)映射到整数域内,并且它们按照行优先的顺序一一对应着 [0, mn)中的每一个整数。形象化地来说,我们把这个二维数组「排扁」成了一个一维数组。其实就是机器学习中的flatten操作

这样的映射即为:
(i,j)→i×n+j(i,j)→i\times n+j (i,j)→i×n+j
同样地,我们可以将整数 xx映射回其在矩阵中的下标,即
{i=x/nj=x\begin{cases} i=x/n\\ j=x%n \end{cases} {i=x/nj=x​

那么题目需要我们做的事情相当于:

将二维数组nums 映射成一个一维数组;

将这个一维数组映射回 r 行 c 列的二维数组。

可以直接从二维数组 nums 得到 r 行 c 列的重塑矩阵:

设nums 本身为 m 行 n 列,如果 mn≠rcmn\not = rcmn​=rc,那么二者包含的元素个数不相同,因此无法进行重塑;

否则,对于 x∈[0,mn),第 x 个元素在 nums 中对应的下标为(x/n,x%n),而在新的重塑矩阵中对应的下标为 (x/c,x%c)。我们直接进行赋值即可。

代码

class Solution {public int[][] matrixReshape(int[][] mat, int r, int c) {int m = mat.length;// 行数int n = mat[0].length;// 列数if (m * n != r * c) {return mat;}int[][] result = new int[r][c];for (int i = 0; i < m * n; i++) {result[i / c][i % c] = mat[i / n][i % n];}return result;}
}

杨辉三角

题目

给定一个非负整数 *numRows,*生成「杨辉三角」的前 numRows 行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

示例

示例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

示例 2:

输入: numRows = 1
输出: [[1]]

提示:

1 <= numRows <= 30

代码实现

class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> result = new ArrayList<List<Integer>>();for (int i = 0; i < numRows; i++) {List<Integer> row = new ArrayList<>();for (int j = 0; j <=i; j++) {if(j==0||j==i){row.add(1);//第一个和最后一个是1}else{row.add(result.get(i-1).get(j-1)+result.get(i-1).get(j));//上一行的左上角加右上角}}result.add(row);}return result;}
}

有效的数独

题目

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

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

注意:

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

示例

示例 1:

输入: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 存在, 因此这个数独是无效的。

按照规则分别判断行、列和小矩型

public class Solution {public boolean isValidSudoku(char[][] board) {for(int i = 0;i<9;i++) {for(int j = 0;j<9;j++) {if (!isValidColumn(board, i, j)) return false;if (!isValidRow(board, i, j)) return false;if(!isValidSmallMatrix(board, i, j)) return false;}}return true;}static boolean isValidRow(char[][] board,int r ,int c) {for(int i = 0;i<9;i++) {if (i!=c &&board[r][c]!='.' ) {if (board[r][c]==board[r][i]) {return false;}}}return true;}static boolean isValidColumn(char[][] board,int r ,int c) {for(int i =0;i<9;i++) {if(i!=r&&board[r][c]!='.') {if(board[i][c]==board[r][c])return false;}}return true;}static boolean isValidSmallMatrix(char[][] board,int r ,int c) {int i = r/3;int j = c/3;for(int p = i*3;p<(i+1)*3;p++) {for(int q = j*3;q<(j+1)*3;q++) {if(board[r][c]!='.'&&board[r][c]==board[p][q]&&(r!=p&&c!=q))return false;}}return true;}
}

标准解法——一次遍历

可以使用哈希表记录每一行、每一列和每一个小九宫格中,每个数字出现的次数。只需要遍历数独一次,在遍历的过程中更新哈希表中的计数,并判断是否满足有效的数独的条件即可。

由于数独中的数字范围是 11 到 99,因此可以使用数组代替哈希表进行计数。

    public boolean isValidSudoku(char[][] board) {int[][] rows = new int[9][9];int[][] columns = new int[9][9];int[][][] submatrix = new int[3][3][9];for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {char c = board[i][j];if (c != '.') {int index = c - '0' - 1;rows[i][index]++;columns[j][index]++;submatrix[i / 3][j / 3][index]++;if (rows[i][index] > 1 || columns[j][index] > 1 || submatrix[i / 3][j / 3][index] > 1) {return false;}}}//只用比较一次,不用一次次的去比较}return true;}

矩阵置零

题目

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

原地算法:在计算机科学中,一个原地算法(in-place algorithm)是一种使用小的,固定数量的额外之空间来转换资料的算法。当算法执行时,输入的资料通常会被要输出的部分覆盖掉。不是原地算法有时候称为非原地(not-in-place)或不得其所(out-of-place)。

通俗的说法:就是一个算法,除了可以运用输入数据本身已开辟的空间外,就只可以用极小的辅助空间来进行运算了,一般 额外空间复杂度为 O(1),也就是一个变量。(特殊情况除外)

示例

示例 1:

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

示例 2:

输入: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]]

O(m+n)复杂度

class Solution {public void setZeroes(int[][] matrix) {Set<Integer> row_zero = new HashSet<>();Set<Integer> col_zero = new HashSet<>();int row = matrix.length;int col = matrix[0].length;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if (matrix[i][j] == 0) {row_zero.add(i);//行如果有0,则加入行数集合col_zero.add(j);//列如果有0,则加入列数集合}}}for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if (row_zero.contains(i) || col_zero.contains(j)) matrix[i][j] = 0;}}  }
}

O(1)复杂度

关键思想: 用matrix第一行和第一列记录该行该列是否有0,作为标志位

但是对于第一行,和第一列要设置一个标志位,为了防止自己这一行(一列)也有0的情况

class Solution {public void setZeroes(int[][] matrix) {boolean firstRow = true;// 判断第一行是否有0boolean firstCol = true;// 判断第一列是否有0for (int i = 0; i < matrix[0].length; i++) {if (matrix[0][i] == 0) {firstRow = false;}}for(int j = 0;j<matrix.length;j++) {if (matrix[j][0] == 0) {firstCol = false;}}for(int i = 1;i<matrix.length;i++) {for(int j = 1;j<matrix[0].length;j++) {if(matrix[i][j]==0) {matrix[i][0]=0;matrix[0][j]=0;}}}for(int i = 1;i<matrix.length;i++) {for(int j = 1;j<matrix[0].length;j++) {if(matrix[i][0]==0||matrix[0][j]==0) {matrix[i][j]=0;}}}//置零//判断第一行和第一列是否为0if(!firstRow) {for(int j = 0;j<matrix[0].length;j++) {matrix[0][j]=0;}}if(!firstCol) {for(int i = 0;i<matrix.length;i++) {matrix[i][0]=0;}}}
}

题目来源

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/reshape-the-matrix

链接:https://leetcode-cn.com/problems/pascals-triangle/

链接:https://leetcode-cn.com/problems/valid-sudoku

链接:https://leetcode-cn.com/problems/set-matrix-zeroes

链接:https://leetcode-cn.com/problems/set-matrix-zeroes/solution/o1kong-jian-by-powcai/

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

LeetCode刷题笔记2——数组2相关推荐

  1. 卷进大厂系列之LeetCode刷题笔记:二分查找(简单)

    LeetCode刷题笔记:二分查找(简单) 学算法,刷力扣,加油卷,进大厂! 题目描述 涉及算法 题目解答 学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给定一个 n 个元素有序的(升序) ...

  2. LeetCode刷题笔记汇总

    LeetCode刷题笔记汇总 第一次刷LeetCode写的一些笔记. 1.两数之和 3.无重复字符的最长子串 15.三数之和 18.四数之和 19.删除链表的倒数第 N 个结点 20.有效的括号 21 ...

  3. LeetCode刷题笔记-动态规划-day4

    文章目录 LeetCode刷题笔记-动态规划-day4 55. 跳跃游戏 1.题目 2.解题思路 3.代码 45. 跳跃游戏 II 1.题目 2.解题思路 3.代码 LeetCode刷题笔记-动态规划 ...

  4. leetcode刷题笔记——二分查找

    leetcode刷题笔记--二分查找 目前完成的贪心相关的leetcode算法题序号: 中等:80,81 困难:4 来源:力扣(LeetCode) 链接:https://leetcode-cn.com ...

  5. LeetCode刷题笔记(算法思想 四)

    LeetCode刷题笔记(算法思想 四) 七.动态规划 斐波那契数列 70. 爬楼梯 198. 打家劫舍 213. 打家劫舍 II 信件错排 母牛生产 矩阵路径 64. 最小路径和 62. 不同路径 ...

  6. 小何同学的leetcode刷题笔记 基础篇(01)整数反转

    小何同学的leetcode刷题笔记 基础篇(01)整数反转[07] *** [01]数学取余法*** 对数字进行数位操作时,常见的方法便是用取余的方法提取出各位数字,再进行操作 操作(1):对10取余 ...

  7. 【leetcode刷题笔记】动态规划

    #[leetcode刷题笔记]动态规划 石子游戏 public boolean stoneGame(int[] piles) {int N = piles.length;// dp[i][j] is ...

  8. LeetCode刷题笔记- 15.三数之和

    LeetCode刷题笔记- 15.三数之和 C语言 题目 注意点 C语言 /*** Return an array of arrays of size *returnSize.* The sizes ...

  9. LeetCode刷题笔记第6题:Z字形变换

    LeetCode刷题笔记第6题:Z字形变换 想法: 要完成字符串根据给定的行数从上往下,从左到右完成Z字形排列.当只有一行时直接返回原字符串,当行数大于1时,先以行数构建一个行数数值个空字符串的列表, ...

最新文章

  1. OpenStack-MitakaCentos7.2双节点搭建--(六)Dashboard服务
  2. 关于json 转换BigDecimal精度丢失问题
  3. c语言函数大全 chm,【oeasy丨c语言丨函数】C语言库函数使用大全CHM版
  4. 设置axios默认访问前缀
  5. 专题导读:科学数据治理
  6. Spike Timing–Dependent Plasticity: A Hebbian Learning Rule ///STDP时空依赖可塑性
  7. mod_wsgi 的两种模式
  8. Mysql server has gone away
  9. Linux学习(3)Linux文件的基本属性、文件内容查看
  10. wordpress评论审核通过发邮件给评论者
  11. 【Gym - 101234J】Zero Game【单调队列】
  12. (转)Java 之 FileReader FileInputStream InputStreamReader BufferedReader 作用与区别
  13. 硬盘格式化后想要数据恢复的详细步骤攻略
  14. 用虚拟机玩游戏的方法!! 开3D加速!
  15. 人脸识别活体检测的几种方法
  16. 2013年中秋节放假安排
  17. MFC中添加一张图片作为对话框(或CFormView)的背景
  18. 腾讯云轻量应用服务器网站搭建基础教程简单易学
  19. 大数据应用电子商务之精准推广
  20. 移动端浏览器触摸事件@touchstart=“touchstart“ @touchend=“touchend“ @touchmove=“touchmove“

热门文章

  1. 计算机思维与应用论文,计算机的思维与计算机应用关系分析
  2. TL437x-EVM评估板测试手册(2)
  3. 对高尔顿数据集实现线性回归分析
  4. 影视后期制作画面、声音、效果如何平衡?
  5. PHP windoews调用OpenOffice实现word/ppt转PDF-附带demo
  6. 回复犹豫的实习生——走好脚下,心怀未来
  7. 华为IT总监离职时给大家写了一封告别信(ZT)
  8. Visual Studio 2010 Power Tool
  9. spark常见面试题
  10. 基于矩阵分解模型的协同过滤理论概述(涉及到SVD,SVD++,TimeSVD++)