LeetCode刷题记录(第十五天)

Reshape the Matrix

原题目:

In MATLAB, there is a very useful function called ‘reshape’, which can reshape a matrix into a new one with different size but keep its original data.

You’re given a matrix represented by a two-dimensional array, and two positive integers r and c representing the row number and column number of the wanted reshaped matrix, respectively.

The reshaped matrix need to be filled with all the elements of the original matrix in the same row-traversing order as they were.

If the ‘reshape’ operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.

翻译:

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

给出一个由二维数组表示的矩阵,以及两个整数rc分别表示想要的重构矩阵号和号。

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

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

事例:

Example 1:

Input: 
nums = 
[[1,2],
 [3,4]]
r = 1, c = 4
Output: 
[[1,2,3,4]]
Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.

Example 2:

Input: 
nums = 
[[1,2],
 [3,4]]
r = 2, c = 4
Output: 
[[1,2],
 [3,4]]
Explanation:
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.

思路:

今天这道题还是比较简单的一道题,也可能是最近一直在做题有一些效果,嘿嘿。题目配合上事例非常好理解,就是把原来的一个二维数组里面的所有元素拿出来组成一个新的维度的二维数组。

1、首先要判断能否构成新的二维数组,像Example 2一样,如果不能,直接返回原数组;

2、遍历传入数组中每一个元素,把它们依次加入到新的二维数组中;

3、新的二维数组大小要定义成传入r与c;

4、通过if else判断放入新数组的位置,并且要做好边界的判断,防止数组越界;

5、当新数组放慢时,返回新的数组。

虽然比较好理解,但是在世纪的编码中,我也是经过了多种用例的测试,测试了很多情况,才完善了我的代码,下面是我自己编写的代码:

package com.mianshi.suanfa.ReshapetheMatrix;

/**
 * Created by macbook_xu on 2018/4/4.
 */
public class Solution {
        public static int[][] matrixReshape(int[][] nums, int r, int c) {
            if (nums.length * nums[0].length < r * c) return nums;

            int[][] newNums = new int[r][c];
            int count = 0 ;
            int row = 0 ;
            int con = 0 ;

            for (int i = 0 ; i<nums.length ; i++){
                for (int j = 0 ; j<nums[i].length ; j++){
                    if (count < c){
                        newNums[row][con] = nums[i][j];
                        con++;
                        count++;
                    }else {
                        row++;
                        con = 0 ;
                        if (row>r-1) return newNums;
                        newNums[row][con] = nums[i][j];
                        con++;
                        count = 1 ;
                    }
                }
            }
            return newNums;
        }

    public static void main(String[] args) {
        int[][] nums = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
        int[][] newNums = matrixReshape(nums,4,2);
        for (int i = 0 ; i<newNums.length ; i++){
            for (int j = 0 ; j<newNums[i].length ; j++){
                System.out.println(newNums[i][j]);
            }
        }
    }
}

完全按照自己的思路编写,虽然不知道这样做是不是会影响效率,但这已经是我能想到最完美的解决方法了。其实在官网上,只要当原数组元素个数不等于新数组元素个数时,都应返回原数组,但是我觉得这道题目当原数组元素个数大于新数组元素个数时也可以转化,如果为了通过题目,可以吧最开始的判断条件改为不等,其实这些细节在工作中主要看业务需求了。

当然,答案中也给出了几种方法:

方法 1

public class Solution {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int[][] res = new int[r][c];
        if (nums.length == 0 || r * c != nums.length * nums[0].length)
            return nums;
        int count = 0;
        Queue < Integer > queue = new LinkedList < > ();
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[0].length; j++) {
                queue.add(nums[i][j]);
            }
        }
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                res[i][j] = queue.remove();
            }
        }
        return res;
    }
}

方法 2

public class Solution {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int[][] res = new int[r][c];
        if (nums.length == 0 || r * c != nums.length * nums[0].length)
            return nums;
        int rows = 0, cols = 0;
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[0].length; j++) {
                res[rows][cols] = nums[i][j];
                cols++;
                if (cols == c) {
                    rows++;
                    cols = 0;
                }
            }
        }
        return res;
    }
}

方法 3

public class Solution {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int[][] res = new int[r][c];
        if (nums.length == 0 || r * c != nums.length * nums[0].length)
            return nums;
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[0].length; j++) {
                res[count / c][count % c] = nums[i][j];
                count++;
            }
        }
        return res;
    }
}

其实方法一和二都和我的思路差不多,只不过方法一使用了队列来存放传入数组的所有元素,但是这样做更耗空间,方法二就和我的基本一样了,边进行遍历边给新的数组赋值,最后直接返回新的数组。当然,我觉得方法三是一个非常好的办法,利用数学的方法来判断,不需要写复杂的条件,非常的高效简单。

点赞