1.关于malloc()函数的简介
看我的另一篇博客C语言笔记:分配内存,malloc与数组
2.题1-力扣118. 杨辉三角
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。
我们需要使用C语言来创建一个动态的二维数组,使它每行的列数等于它的行数。
首先通过malloc()函数来开辟整个二维数组的空间:
malloc()函数:
malloc函数会返回开辟空间的首地址,加(int *)的目的是让计算机知道,如何去划分这个开辟的空间,因为char、int 、long这些类型的字节大小是不一样的,我们知道了首地址,还要知道是以几个字节为单元。所以,这句话一共开辟了8个字节(某些计算机上),这也是为什么我写sizeof(int),而不是直接写4的原因。
————————————————
引用于https://blog.csdn.net/sinat_29957455/article/details/60883355
int** ret = malloc(sizeof(int*) * numRows);
其中,声明了ret是int* * 型指针,它只能指向int*型的对象。
即,ret中储存的是一个储存单元的地址,该储存单元中储存的数据是另外一个储存单元的地址,另外的这个储存单元储存的是一个数值,可以通过**ret访问。
malloc()函数返回的是一个无类型指针,需要在前面加上强制类型转换:
int** ret = (int**)malloc(sizeof(int*) * numRows);
现在已经通过malloc()函数分配了numRows个指针类型字节长度空间,但每一块空间内都包含着一个未被开辟子空间,所以我们需要对这些空间再次分配内存:
for(int i=0; i<numRows; i++)
ret[i] = (int*)malloc(sizeof(int) * (i + 1));
这样,二维数组就创建好了,并且数组每一行的列数都等于行数。
其中ret[i]可以看作是一个一维数组,这里看一下如何建立一维动态数组
int *num;
num = (int *)malloc(N * sizeof(int));
如此,为num开辟了一个存有N个int型的数组空间。
根据题意的要求,我们需要得出返回的行、列的大小。
其中行的大小为
*returnSize = numRows;
列的大小是储存在一个数组中的,同样,先开辟空间分配内存,再赋值。
*returnColumnSizes = malloc(sizeof(int) * numRows);
for(int i=0; i<numRows; i++)
(*returnColumnSizes)[i] = i + 1;
这里的*returnColumnSizes可以看作是一个一维数组。
最后,通过数学方法可以计算出题目的答案,即每个数字等于上一行左右两个数字之和,且每行第一个和最后一个数字为1,代码如下:
int** generate(int numRows, int* returnSize, int** returnColumnSizes){
int** ret = (int*)malloc(sizeof(int*) * numRows);
*returnSize = numRows;
*returnColumnSizes = malloc(sizeof(int) * numRows);
for(int i=0; i<numRows; i++){
ret[i] = malloc(sizeof(int) * (i + 1));
(*returnColumnSizes)[i] = i + 1;
ret[i][0] = ret[i][i] = 1;
for(int j=1; j<i; j++){
ret[i][j] = ret[i-1][j-1] + ret[i-1][j];
}
}
return ret;
}
2.题2-力扣566. 重塑矩阵
在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x
c)的新矩阵,但保留其原始数据。给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。
如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
第一种解法:
先将原矩阵的数值存到一维数组里,再重塑为新矩阵。
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
int z = 0;
//定义返回的二维矩阵
int** ret = (int**)malloc(sizeof(int*) * r);
//定义用于传递的一维向量
int* nums = (int*)malloc(sizeof(int) * (r * c));
//判断是否满足重塑条件,即行*列是否相等
if(matSize * matColSize[0] == r * c){
//为返回的行数赋值,为列数开辟储存空间
*returnSize = r;
*returnColumnSizes = (int*)malloc(sizeof(int) * r);
//将原矩阵按序赋给一维数组
for(int i=0; i<matSize; i++){
for(int j=0; j<matColSize[0]; j++){
nums[z++] = mat[i][j];
}
}
z = 0;
//将一维数组赋给重塑矩阵
for(int i=0; i<r; i++){
(*returnColumnSizes)[i] = c;//每一行的列数都是c
ret[i] = (int*)malloc(sizeof(int) * c);//为重塑矩阵中的每一行开辟列空间。
for(int j=0; j<c; j++){
ret[i][j] = nums[z++];
}
}
return ret;
}
//不能重塑,直接返回原矩阵
else{
*returnSize = matSize;
*returnColumnSizes = matColSize;
}
return mat;
}
第二种解法:
直接从原矩阵里得到重塑矩阵。
具体的思路可以看《官解》。
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){
int** ret = (int**)malloc(sizeof(int*) * r);
if(matSize * matColSize[0] == r * c){
*returnSize = r;
*returnColumnSizes = (int*)malloc(sizeof(int) * r);
for(int i=0; i<r; i++){
(*returnColumnSizes)[i] = c;
ret[i] = (int*)malloc(sizeof(int) * c);
}
for(int j=0; j<r*c; j++){
ret[j/c][j%c] = mat[j/(*matColSize)][j%(*matColSize)];
}
return ret;
}
else{
*returnSize = matSize;
*returnColumnSizes = matColSize;
}
return mat;
}