@Leetcode杨辉三角
似乎不再是树类型的题目了,今天我们来看一下最简单的动态规划,也就是大佬们所说的dp问题,请看题干:
给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
示例:
杨辉三角属于动态规划类型题中最为简单易懂好理解的一个。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。对应杨辉三角,就是一个典型的动态规划题,请看代码:
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> final(numRows);
if(numRows==0)
return final;
for(int i=0;i<numRows;i++){
for(int j=0;j<=i;j++){
if(j==0||j==i)
final[i].push_back(1);
else
final[i].push_back(final[i-1][j-1]+final[i-1][j]);
}
}
return final;
}
};
思路简单易懂,我们很容易发现,杨辉三角的数字得到有三个基本规律:
1.三角最上方的数字为1。
2.三角每一行最两侧的两个数字为1(除去最高行)。
3.每个不满足前两个规律的数字,都是由前一行正上方左侧的数字和正上方右侧的数字相加得到。
有了这三个规律我们就可以开始构思我们的代码了,只需要针对这三种情况进行讨论就行。在开始编程之前先注意两层vector的定义,我们也需要开辟一个两层的vector用于存放做为答案输出的数组。首先判断所给的行数是否小于1,如果小于1直接放回就行,注意这里是返回答案数组而不是返回NULL(笔者的第一个WA)。接着对数组挨个进行赋值操作,定义的是一个两层的vector也就类似于一个二维数组,操作起来要留心一下vector的特殊的加入元素的方法即可。下面的图片是小白笔者的一个十分低级的错误,也是笔者的第二个WA:
大家在写循环时一定要注意循环的起点与终点,如果I从0开始的话,j也就从0开始,此时一定要明确最上面的1的存储是在final的第0层,而不是第1层,以此类推,所以两侧元素的赋值并不是jI-1的时候,而是jI的时候。
解决了这个问题之后我们可以看到非两侧元素的赋值是final[I-1][j]+final[I-1][j],这个只要大家细心推一下个数,相信都不是问题。整个代码严格符合上面所说的三种规律的考虑模式,虽说思路简单,也还是有些小乾坤的哦,希望大家有所收获。