杨辉三角的基本性质
想要做出这类题,首先要了解这些基本概念,相信大家也都知道:
- 每行数字左右对称,并且是从1开始变大,再变小回到1。
- 从0下标开始,第n行有 n+1 个元素。
- 每个数字等于上一行的左右两个数字之和。
题目1
leetcode 118.杨辉三角
题目链接:
118.杨辉三角
题解(C语言)
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
每行都会写注释,而且方法很老实,希望人人都可以看懂~
/**
* 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)
{
//动态申请二维数组作为返回答案,题目要求numRows行
int** ans = (int**)malloc(sizeof(int*) * numRows);
if (ans == NULL) return NULL;
//根据题意,*returnSize返回答案数组行的长度,即numRows行
*returnSize = numRows;
//这个数组需要保存的是每行有多少个元素
//所以动态申请一个一维数组,大小刚好等于行数
*returnColumnSizes = (int*)malloc(sizeof(int) * numRows);
int i = 0, j = 0;
//这个循环是从0到numRows,即想要遍历每一行数组
//1.将为返回答案的二维数组的每一行动态申请一维数组,
//2.并将每行的元素个数保存到*returnColumnSizes数组中
//3.因为是杨辉三角,所以将返回答案的每一行的最左端和最右端置为1.
for (i = 0; i < numRows; ++i)
{
ans[i] = (int*)malloc(sizeof(int) * (i + 1));
(*returnColumnSizes)[i] = i + 1;
ans[i][0] = ans[i][i] = 1;
}
//这个双重循环,外层控制行数,从第三行开始
//内层对每行依次赋值,每行有行号加1个元素
for (i = 2; i < numRows; ++i)
{
for (j = 1; j < i; ++j)
{
//这里用到了开局说的性质,每个数都是上一行左右两个数之和
ans[i][j] = ans[i - 1][j - 1] + ans[i - 1][j];
}
}
//返回答案
return ans;
}
运行结果
纯享版
没有注释,好看点
int** generate(int numRows, int* returnSize, int** returnColumnSizes)
{
int** ans = (int**)malloc(sizeof(int*) * numRows);
if (ans == NULL) return NULL;
*returnColumnSizes = (int*)malloc(sizeof(int) * numRows);
int i = 0, j = 0;
for (i = 0; i < numRows; ++i)
{
ans[i] = (int*)malloc(sizeof(int) * (i + 1));
(*returnColumnSizes)[i] = i + 1;
ans[i][0] = ans[i][i] = 1;
}
for (i = 2; i < numRows; ++i)
{
for (j = 1; j < i; ++j)
{
ans[i][j] = ans[i - 1][j - 1] + ans[i - 1][j];
}
}
*returnSize = numRows;
return ans;
}
题目2
leetcode 119.杨辉三角||
题目链接:
119.杨辉三角||
题解(C语言)
给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
可以和上面一样,用老实的方法做,这是方法简单,好掌握。
int* getRow(int rowIndex, int* returnSize)
{
//杨辉三角特性,第n行有n+1个元素
*returnSize = rowIndex + 1;
int* ans[rowIndex + 1];
for (int i = 0; i <= rowIndex; ++i)
{
ans[i] = (int*)malloc(sizeof(int) * (i + 1));
ans[i][0] = ans[i][i] = 1;
for (int j = 1; j < i; ++j)
{
ans[i][j] = ans[i - 1][j] + ans[i - 1][j - 1];
}
}
return ans[rowIndex];
}
优化
只申请一行空间,即用一个一维数组。
因为杨辉三角的每个元素都是他上一行左右两数之和,示例:
nums[i] = nums[i - 1] + nums[i]
那只要从后往前处理,就不需要考虑数组元素被覆盖的问题。
C语言代码
int* getRow(int rowIndex, int* returnSize)
{
//申请一维数组
int* ans = (int*)malloc(sizeof(int) * (rowIndex + 1));
memset(ans, 0, sizeof(int) * (rowIndex + 1));
//先将第一行初始化
ans[0] = 1;
for (int i = 1; i < rowIndex + 1; ++i)
{
//从后往前处理
for(int j = i; j > 0; --j)
{
//性质:每位元素都是它上一行的左右两数和
ans[j] = ans[j - 1] + ans[j];
}
}
//返回长度和数组
*returnSize = rowIndex + 1;
return ans;
}
运行结果:
我和大多数人一样都是新手,菜鸟,如果文章有错误,请大家指正,谢谢大家。