LeetCode:566. 重塑矩阵
在MATLAB中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。
给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。
如果具有给定参数的reshape操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
示例 :
输入:
nums =
[[1,2],
[3,4]]
r = 1, c = 4
输出:
[[1,2,3,4]]
解释:
行遍历nums的结果是 [1,2,3,4]。新的矩阵是 1 * 4 矩阵, 用之前的元素值一行一行填充新矩阵。
这个主要就是遍历二维数组,也就是矩阵。
class Solution { public int[][] matrixReshape(int[][] mat, int r, int c) { int matHeight = mat.length; int matLength = mat[0].length; if(matHeight*matLength != r*c){ return mat; } int [][] result = new int[r][c]; int resultHeight=0,resultLength=0; //老老实遍历一遍 for(int i=0;i<matHeight;i++){ for(int j=0;j<matLength;j++){ result[resultHeight][resultLength] = mat[i][j]; if(resultLength<c-1){ resultLength++; }else if(resultHeight<r-1){ resultLength = 0; resultHeight++; }else { return result; } } } return result; } }
时间复杂度:O(m*n),空间复杂度:O(1)。
果然,没有学过机器学习,一下子没想到官方的算法。
对于一个行数为 m,列数为 n,行列下标都从 0 开始编号的二维数组,我们可以通过下面的方式,将其中的每个元素 (i, j) 映射到整数域内,并且它们按照行优先的顺序一一对应着 [0, mn) 中的每一个整数。形象化地来说,我们把这个二维数组「排扁」成了一个一维数组。如果读者对机器学习有一定了解,可以知道这就是 flatten 操作。
这样的映射即为:
(i,j) → i×n+j
同样地,我们可以将整数 x 映射回其在矩阵中的下标,即
i=x / n
j=x % n
其中 / 表示整数除法,% 表示取模运算。
class Solution { public int[][] matrixReshape(int[][] nums, int r, int c) { int m = nums.length; int n = nums[0].length; if (m * n != r * c) { return nums; } int[][] ans = new int[r][c]; for (int x = 0; x < m * n; ++x) { ans[x / c][x % c] = nums[x / n][x % n]; } return ans; } }
时间复杂度:O(m*n),空间复杂度:O(1)。
不过代码优雅多了。