C/C++解OJ题--杨辉三角||(动态规划之搬砖)
作者:互联网
前言:
动态规划的题目做了有几题了,根据动态规划的思想及解题步骤似乎总是能成功,真的有那么万能吗?我们再来验证一下。
动态规划解题步骤:
1. 定义dp数组所表示的含义
动态规划类型的题目我们会用一个临时变量,目的是保存历史数据,避免像使用递归而产生大量的重复计算。这个变量或许是一维数组,或许是二维数组,根据题目不同而不同。通常我们将这个数组称为dp(Dynamic Programming) 数组。
我们要明确dp数组中下标所表示的含义及数组元素所代表的意思。
2. 确定递推公式
通俗的说就是确定数组元素之间的关系,通过该递推公式可以由子问题的解统计出大问题的解。递推公式的确定常用最后一步和子问题来确定。
3. 定义初始条件及边界
对于一些不能用递推公式分解得出的我们要直观的给出答案。边界情况,自然数组不能越界
4. 遍历顺序(计算顺序)
根据递推公式判读应该按照怎样的遍历顺序或者计算顺序进行计算(小->大;大->小)。要求解递推公式左边的必须知道递推公式右边的。
原题如下:
给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
审题:
根据题意我们只需要返回杨辉三角的某一行的数据。并且本题中若给我们的rowIndex为3,那么我们要返回杨辉三角的第4行数据(逻辑顺序上的计数)。同时说明我们开辟的数组大小应该为rowIndex+1。
思路:
1.开辟一个数组大小为rowIndex+1的数组
2.根据动态规划的思想不断更新数组中的数据,那么最后数组中的数据即为最后的结果。
按步就搬:
1. 定义dp数组所表示的含义
题目要求我们返回杨辉三角的第rowIndex行,则我们定义杨辉三角的第 i 行的数据为 dp[0~i];
2. 确定递推公式
最后一步: 假设要返回递推公式的第i行,现在我们已经知道了第i-1行的数据。而题目描述在「杨辉三角」中,每个数是它左上方和右上方的数的和。即为第i-1行的第一个数据+第二个数据=第i行的第二个数据……所以递推公式为:dp[i]=dp[i-1]+dp[i]。等式左边的代表下一行所要求解的数据,而等式右边的代表本行的数据。通过不断地更新覆盖,就会得出下一行的数据。
3. 定义初始条件及边界
根据递推公式dp[0]是不能由递推公式分解得出(数组下标无负数),所以要给出每一行的dp[0]=1。
其次第 i 行的最后一个数据是不能由递推公式得出,因为第i-1行的数据不存在数组下标为 i 的数据,会发生数组越界。所以要显示的将每一行的最后一个数据都赋值为1。
4. 遍历顺序(计算顺序)
通过上述分析所得,存在嵌套的两层循环。第一层循环用于控制第几行,第二层循环用于计算该行的数据。
由于我们是通过所申请的原始数组中直接进行计算,也就意味着在计算的时候不能将下一次所要的计算数据给覆盖了。因此对于第二层的计算顺序应该从大到小。
假设现在我们已经知道了第rowIndex=2行的数据,目标是求解第rowINdex=3行的数据,如下:
既然目标是求解第rowIndex=3行的数据,如果采取从小到大进行遍历,那么当计算完数组下标为1号位置的数据后,下一次计算所需要的数据2已经被覆盖为了数据3。如下:
这也就不能正确得到2号位置的数据,所以要从大到小进行遍历。
代码实现:
int* getRow(int rowIndex, int* returnSize){
int*dp=(int*)malloc(sizeof(int)*(rowIndex+1));//开辟dp数组,大小为rowIndex+1
*returnSize=rowIndex+1;
for(int i=0;i<=rowIndex;i++)//通过不断的更新迭代直到到达目标第rowIndex行
{
for(int j=i;j>=0;j--)//数组下标从大到小进行遍历
{
if(j==0||j==i)//不能由递推公式分解得出的要直观的给出答案
{
dp[j]=1;
}
else//能用递推公式求解的部分
{
dp[j]=dp[j]+dp[j-1];
}
}
}
return dp;//返回最后数组中的结果
}
我是老胡,感谢阅读!!❤️ ❤️
标签:OJ,--,数据,rowIndex,数组,公式,杨辉三角,递推,dp 来源: https://blog.csdn.net/qq_53524653/article/details/121870057