描述
在 MATLAB 中,有一个非常有用的函数 reshape
,它可以将一个 m x n
矩阵重塑为另一个大小不同(r x c
)的新矩阵,但保留其原始数据。
给你一个由二维数组 mat
表示的 m x n
矩阵,以及两个正整数 r
和 c
,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的 reshape
操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
示例 1:
输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]
示例 2:
输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 100
-1000 <= mat[i][j] <= 1000
1 <= r, c <= 300
通过次数76,096提交次数111,560
做题
这道题没有那么难,我们都会遍历二维数组吧。
像这样。
public static void main(String[] args) {
int[][] array ={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
for (int i = 0; i < array.length; i++) {
for (int j=0;j< array[i].length;j++){
System.out.println(array[i][j]);
}
}
}
往新数组填值的逻辑就是跟遍历数组一样。
比较难的地方就是怎么从旧数组取值?
比如 mat[n][m]
当 m == array[n].length 时,就重新赋值为 0,n++。
当 n == array.length 时,退出。
敲码!
public int[][] matrixReshape(int[][] mat, int r, int c) {
int[][] result = new int[r][c];
//旧数组的索引
int n = 0,m=0;
for (int i = 0; i < r; i++) {
for (int j=0;j< c;j++){
result[i][j]=mat[n][m++];
if (m==mat[n].length){
m=0;
n++;
if (n==mat.length){
break;
}
}
}
}
return result;
}
??
给力扣摆了一道,居然给的 r 和 c 建的数组对不上原来的数组?!
我自己测试了一下,如果 r * c 和原数组一样的话,是可以转换成功的。
原来是我没有看清题目,Sorry。
再加上一段逻辑,就可以了。
看着占用内存和执行时间,就知道这个算法有非常大的优化空间。
看了大佬的算法,发现我这种做法是最笨的。
牛逼的做法是通过余数的方法,通过求余获取下标,根本不需要双层循环。
public int[][] matrixReshape1(int[][] mat, int r, int c) {
int[][] result = new int[r][c];
int n = mat.length,m=mat[0].length;
if (r * c != n*m){
return mat;
}
for (int i = 0; i < n*m; i++) {
result[i/c][i%c]=mat[i/m][i%m];
}
return result;
}
运行!
执行时间直接拉到极限!
array[i][j]
需要注意,i 是通过除法获得的,不能通过余数。
最后
这道题算是打破了我对数组的认识,之前一直把二维数组就当成二维数组,想要移到下一行就必须得 i++,现在我们就可以把数组当成一条很长的数组,我们可以通过求余和除法去找到对应在二维数组上的坐标。
今天就到这里了。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。