566.重塑矩阵
在 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来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reshape-the-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
idea:
首先判定r*c是否大于matSize*matColSize,如果大于或小于则返回原矩阵。如果相等则遍历给出的数组,并依次加入到新的数组中即可。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
if((matSize*(*matColSize))!=(r*c)){
*returnSize=matSize;
*returnColumnSizes=matColSize;
return mat;
}
*returnColumnSizes=malloc(sizeof(int)*r);
int** ret=(int **)malloc(sizeof(int*)*r);
for(int i=0;i<r;i++){
(*returnColumnSizes[i])=c;
ret[i]=malloc(sizeof(int)*c);
}
int retR=0,retC=0;
for(int i=0;i<matSize;i++){
for(int j=0;j<matColSize[0];j++){
if(retC<c){
ret[retR][retC]=mat[i][j];
retC++;
}else{
retR++;
retC=0;
}
}
}
*returnSize=r;
return ret;
}
执行代码的时候没有错,但是真正提交的时候就报了以下大段错。。离谱
=================================================================
==42==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffd259d548 at pc 0x55b0d6f53268 bp 0x7fffd259d2f0 sp 0x7fffd259d2e0
READ of size 8 at 0x7fffd259d548 thread T0
#2 0x7f4d3464d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Address 0x7fffd259d548 is located in stack of thread T0 at offset 360 in frame
This frame has 7 object(s):
[32, 36) 'size_1'
[96, 100) 'ret_size'
[160, 168) 'nbytes'
[224, 232) 'line'
[288, 296) 'colsize_1'
[352, 360) 'ret_colsize' <== Memory access at offset 360 overflows this variable
[416, 420) 'SEPARATOR'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
0x10007a4aba50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007a4aba60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007a4aba70: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x10007a4aba80: 04 f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2 f2 f2
0x10007a4aba90: 00 f2 f2 f2 f2 f2 f2 f2 00 f2 f2 f2 f2 f2 f2 f2
=>0x10007a4abaa0: 00 f2 f2 f2 f2 f2 f2 f2 00[f2]f2 f2 f2 f2 f2 f2
0x10007a4abab0: 04 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00
0x10007a4abac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007a4abad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007a4abae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007a4abaf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==42==ABORTING
后来报错的原因也找到了,因为把(*returnColumnSizes)[i]=c;写成了(*returnColumnSizes[i])=c;。所以本应该在*returnColumnSizes里找到数据,但是放在了returnColumnSizes里,编译器找不到。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
if((matSize*(*matColSize))!=(r*c)){
*returnSize=matSize;
*returnColumnSizes=matColSize;
return mat;
}
*returnColumnSizes=malloc(sizeof(int)*r);
int** ret=(int **)malloc(sizeof(int*)*r);
for(int i=0;i<r;i++){
(*returnColumnSizes)[i]=c;
ret[i]=malloc(sizeof(int)*c);
}
int retR=0,retC=0;
for(int i=0;i<matSize;i++){
for(int j=0;j<matColSize[0];j++){
if(retC<c){
ret[retR][retC]=mat[i][j];
retC++;
}else{
retR++;
retC=0;
}
}
}
*returnSize=r;
return ret;
}
不过最后还是有题目不能AC
解法:
二维数组的一维表示。
代码实现的细节学习:
容易遗忘的二维数组以及LC中用C写的returnColumnSizes需要遍历赋值,分配内存时,记得使用把*ans变为数组的形式ans[i]进行分配空间,否则只会分配第一个空间。
//r=row,c=col,returnColumnSizes的变量类型为int **
*returnColumnSizes=malloc(sizeof(int)*r);
int** ans = malloc(sizeof(int*) * r);
for (int i = 0; i < r; i++) {
(*returnColumnSizes)[i] = c;//此处的括号注意不要写成(*returnColumnSizes[i])
ans[i] = malloc(sizeof(int) * c);
}
最后使用答案的flatten写法,mat[x/c][x%c]可以把二维数组转化为一维数组。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
if((matSize*(*matColSize))!=(r*c)){
*returnSize=matSize;
*returnColumnSizes=matColSize;
return mat;
}
*returnSize=r;
*returnColumnSizes=malloc(sizeof(int)*r);
int** ret=(int **)malloc(sizeof(int*)*r);
for(int i=0;i<r;i++){
(*returnColumnSizes)[i]=c;
ret[i]=malloc(sizeof(int)*c);
}
for(int i=0;i<r*c;i++){
ret[i/c][i%c]=mat[i/matColSize[0]][i%matColSize[0]];
}
return ret;
}
118.杨辉三角
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
示例 2:输入: numRows = 1
输出: [[1]]
提示:
1 <= numRows <= 30
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pascals-triangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
idea:
利用杨辉三角的数学性质求解。
代码实现细节的学习:
在C中二维数组的每一行可以拥有不相同的列数。
杨辉三角的实现记忆即可。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** generate(int numRows, int* returnSize, int** returnColumnSizes){
*returnSize=numRows;
*returnColumnSizes=malloc(sizeof(int)*numRows);
int** ret=(int **)malloc(sizeof(int*)*numRows);
for(int i=0;i<numRows;i++){
(*returnColumnSizes)[i]=i+1;
ret[i]=malloc(sizeof(int)*(i+1));
ret[i][0]=ret[i][i]=1;
for(int j=1;j<i;j++){
ret[i][j]=ret[i-1][j]+ret[i-1][j-1];
}
}
return ret;
}