【力扣】566. 重塑矩阵

以下为力扣官方题解

题目

M A T L A B MATLAB MATLAB 中,有一个非常有用的函数 r e s h a p e reshape reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。
给出一个由二维数组表示的矩阵,以及两个正整数 r r r c c c,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。
如果具有给定参数的 r e s h a p e reshape reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

示例1

输入: n u m s = [ [ 1 , 2 ] , [ 3 , 4 ] ] nums = [[1,2], [3,4]] nums=[[1,2],[3,4]] r = 1 , c = 4 r = 1, c = 4 r=1,c=4
输出: [ [ 1 , 2 , 3 , 4 ] ] [[1,2,3,4]] [[1,2,3,4]]
解释: 行遍历 n u m s nums nums 的结果是 [ 1 , 2 , 3 , 4 ] [1,2,3,4] [1,2,3,4]。新的矩阵是 1 ∗ 4 1 * 4 14 矩阵, 用之前的元素值一行一行填充新矩阵。

示例2

输入: n u m s = [ [ 1 , 2 ] , [ 3 , 4 ] ] nums = [[1,2], [3,4]] nums=[[1,2],[3,4]] r = 2 , c = 4 r = 2, c = 4 r=2,c=4
输出: [ [ 1 , 2 ] , [ 3 , 4 ] ] [[1,2], [3,4]] [[1,2],[3,4]]
解释:没有办法将 2 ∗ 2 2 * 2 22 矩阵转化为 2 ∗ 4 2 * 4 24 矩阵。 所以输出原矩阵。

注意

  1. 给定矩阵的宽和高范围在 [ 1 , 100 ] [1, 100] [1,100]
  2. 给定的 r r r c c c 都是正数。

官方题解 二维数组的一唯表示

思路与算法

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

这样的映射即为: ( i , j ) → i × n + j (i, j) \to i \times n+j (i,j)i×n+j

同样地,我们可以将整数 x x x 映射回其在矩阵中的下标,即 { i = x   /   n j = x   %   n \begin{cases} i = x ~/~ n \\ j = x ~\%~ n \end{cases} {i=x / nj=x % n

其中 / / / 表示整数除法, % \% % 表示取模运算。

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

  • 将二维数组 n u m s nums nums 映射成一个一维数组;
  • 将这个一维数组映射回 r r r c c c 列的二维数组。

我们当然可以直接使用一个一维数组进行过渡,但我们也可以直接从二维数组 n u m s nums nums 得到 r r r c c c 列的重塑矩阵:

  • n u m s nums nums 本身为 m m m n n n 列,如果 m n ≠ r c mn \neq rc mn=rc,那么二者包含的元素个数不相同,因此无法进行重塑;
  • 否则,对于 x ∈ [ 0 , m n ) x \in [0, mn) x[0,mn),第 x x x 个元素在 n u m s nums nums 中对应的下标为 ( x   /   n , x   %   n ) (x ~/~ n, x~\%~ n) (x / n,x % n),而在新的重塑矩阵中对应的下标为 ( x   /   c , x   %   c ) (x ~/~ c, x~\%~ c) (x / c,x % c),我们直接进行赋值即可。

代码

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 ( r c ) O(rc) O(rc)。这里的时间复杂度是在重塑矩阵成功的前提下的时间复杂度,否则当 m n ≠ r c mn \neq rc mn=rc 时,直接返回原数组的对象,需要的时间复杂度仅为 O ( 1 ) O(1) O(1)
  • 空间复杂度: O ( 1 ) O(1) O(1)。这里的空间复杂度不包含返回的重塑矩阵需要的空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值