Day04:组合数——杨辉三角

杨辉三角的基本性质

想要做出这类题,首先要了解这些基本概念,相信大家也都知道:

  1. 每行数字左右对称,并且是从1开始变大,再变小回到1。
  2. 从0下标开始,第n行有 n+1 个元素。
  3. 每个数字等于上一行的左右两个数字之和
    在这里插入图片描述

题目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;
}

运行结果:
在这里插入图片描述

我和大多数人一样都是新手,菜鸟,如果文章有错误,请大家指正,谢谢大家。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_索伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值