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)。

不过代码优雅多了。

 

posted @ 2021-04-25 15:11  蜗壳吃虾米  阅读(61)  评论(0)    收藏  举报