1.题目描述:
给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充,不合理则输出原始矩阵。
2.自己写的代码:
使用临时的一维数组来存放mat数组元素的值,再循环遍历放入结果数组中。ps:idea用惯了这里for()循环少了一个括号debug半天。。。
class Solution {
public int[][] matrixReshape(int[][] mat, int r, int c) {
int[][] resArr = new int[r][c];
if(mat.length * mat[0].length != r*c){
return mat;
}else{
int[] arr = new int[mat.length * mat[0].length];
int index = 0;
int resIndex = 0;
for(int i = 0;i < mat.length;i++){
for(int j = 0;j < mat[0].length;j++){
arr[index++] = mat[i][j];
}
}
for(int i = 0;i < r;i++){
for(int j = 0;j < c;j++){
resArr[i][j] = arr[resIndex++];
}
}
return resArr;
}
}
}
3.官方解法:
将给出的二维数组映射成一维数组,m行n列,映射为[0,m * n)的整数域中。映射公式为:(i,j)→ i * n + j;同理可将结果输出的二维数组,r行c列,映射到[0,r * c)的整数域中,需要保证m * n的值和r * c的值相同,从而整数域中的值一一对应。
解释:对于二维数组中的元素mat[i][j],在他前面共有i行,当前i行共有j个元素,所以mat[i][j]是二维数组中或者说是映射过去的一维数组中的第i * n + j + 1个元素,也就是一维数组的索引为i * n + j。反之若映射过来的一维数组索引为x,则对应的二维数组索引为[x / n][x % n]。映射后,两者元素一一对应。
图解一下方便理解:
只把原mat数组映射为一维数组的解法如下:
class Solution {
public int[][] matrixReshape(int[][] mat, int r, int c) {
int[][] resArr = new int[r][c];
int x = 0;
int n = mat[0].length;
if(mat.length * n != r*c){
return mat;
}else{
for(int i = 0;i < r;i++){
for(int j = 0;j < c;j++){
resArr[i][j] = mat[x / n][x % n];
x++;
}
}
return resArr;
}
}
}
把原mat数组和重塑数组都映射为一维数组的解法如下:
class Solution {
public int[][] matrixReshape(int[][] mat, int r, int c) {
int[][] resArr = new int[r][c];
int x = mat[0].length;
if(mat.length * x != r*c){
return mat;
}else{
for(int i = 0;i < r * c;i++){//只需要映射后的一维数组遍历即可
resArr[i / c][i % c] = mat[i / x][i % x];//分别映射为各自的二维数组
}
return resArr;
}
}
}