zoukankan      html  css  js  c++  java
  • JS LeetCode 566. 重塑矩阵题解分析,数组降维的几种方式

    壹 ❀ 引

    今天是过完年到公司的第二天,年前因为封版,到今天我们小组是第一个发版的组,然后就各种踩坑,到现在还在公司等运维解决jenkins问题,闲着也是闲着,做一道算法题,简单记录下解题思路,本题来自LeetCode566. 重塑矩阵,描述如下:

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

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

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

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

    示例 1:

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

    示例 2:

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

    注意:

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

    贰 ❀ 简单的题解

    题目不难理解,给定一个二维数组,将其转换成一个包含r个数组,且每个数组包含c个元素的新数组。比如例子1中,就是将原数组转为包含1个数组且数组元素为4个的新数组。

    需要注意的是,也可能存在转换失败的情况,比如例子2,原数组一共就只有4个元素,而期望是转成包含2个数组,且每个数组包含4个元素的新数组,数量超过了原数组元素数量,转换失败时期望返回原数组。

    因此我们可以得知,不管怎么转换,转换之后的数组元素一定得跟原数组保持一次,只要数量不相同则说明不符合转换规则,返回原数组即可。

    所以最简单的思路就是将原数组进行降维,将其变为一维数组,之后执行r次裁剪操作,每次裁剪c个元素构成一个子数组,将其加入到需要返回的新数组中即可。

    直接上代码:

    /**
     * @param {number[][]} nums
     * @param {number} r
     * @param {number} c
     * @return {number[][]}
     */
    var matrixReshape = function (nums, r, c) {
        // 先判断处理之后的数组长度是否跟之前相等
        // 小知识,不管几维数组,转字符串后再还原成数组都可以做到降维的效果
        let arr = nums.join().split(',');
        if (arr.length !== r * c) {
            return nums;
        };
        // 现在要做的就是执行r次裁剪操作,每次取c个元素组成一个子数组,并加入到新数组
        const res = [];
        for(let i = 0;i < r;i++){
          	// splice会修改原数组,因此我们每次都从0开始裁剪c个是完全没问题的
            res.push(arr.splice(0,c));
        }
        return res;
    };
    

    叁 ❀ 数组降维几种方式

    在做这道题之前,我理解的数组降维最直观的做法就是使用flat。flat接受一个数组并对其做降维操作,默认只降维一层,比如:

    // 这是一个二维数组
    let arr = [[1],[2]];
    // 默认降维一次,因为会得到一个一维数组
    let arr_ = arr.flat();
    // 返回一个新数组,不会修改原数组
    arr//[[1],[2]]
    arr_//[1,2]
    

    flat并不会修改原数组,而是在降维后返回一个新数组。falt可以接受一个参数,表示你希望降维的次数,比如我们有一个三维数组,想降成一维,传递的参数就应该是2:

    [1,[2,[3]]].flat(2);//[1,2,3]
    

    但事实上,我们可能要做降维操作,但不知道数组是几维,因此可以传递传输为Infinity,这样不管是几维,都将得到一个新的一维数组:

    [[[[[1]]]]].flat(Infinity);//[1]
    

    当然,我们可以自己模拟实现一个flat,比如这样:

    function flat_(arr) {
        if (!Array.isArray(arr)) {
            throw new Error('The argument must be an array.');
        };
        return arr.reduce((accumulator, currentValue) => {
            return accumulator.concat(Array.isArray(currentValue) ? flat_(currentValue) : currentValue);
        }, []);
    };
    

    而在今天做了这道题之后,我发现原来将数组转为字符串,再还原成数组也能做到数组降维的操作,比如

    ([1,[2],[3,[4]]]+'').split(',')// [1,2,3,4]
    

    而这里的原理仅仅是用了数组与字符串相加的隐式转换。同理,join也能将数组还原成字符,因此下面这段代码拥有相同效果:

    [1,[2],[3,[4]].join().split(',')// [1,2,3,4]
    

    马上11点了,发版也完成了,那么本文结束,下班下班!

  • 相关阅读:
    PHP数据库连接mysql与mysqli的区别与用法
    PHP自定义环境搭建(apache、php)
    2021-11-04 CCPC女生赛 ABCDGIK 题解
    Virtual Judge 20211026 日常训练 ABCDEFG题解
    Spring AOP:@DeclareParents 为对象添加方法
    Spring AOP:@Around 的 JavaConfig 写法
    Spring AOP:@Before、@After 的 JavaConfig 写法
    spring事务传播属性
    缓存与数据库的一致性问题怎么解决
    Java多线程之CyclicBarrier
  • 原文地址:https://www.cnblogs.com/echolun/p/14418518.html
Copyright © 2011-2022 走看看