1.模拟 动态规划
118的状态转移公式 dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
可以看到可将[i-1],[i]省掉 只返回指定行
// dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
vector<int> getRow(int rowIndex) {
vector<int> a;
for(int i=0;i<=rowIndex;++i)
{
a.push_back(1);
for(int j=i-1;j>0;--j)
{ //从后向前遍历 也可从前向后遍历
a[j]+=a[j-1];
}
}
return a;
}
模拟法(动态规划)
特判,若k= =0 k==0,返回[1][1]
初始化dp=[1,1]dp=[1,1],表示第二行
遍历区间[3,k+2)[3,k+2),表示从第三行开始遍历:
初始化cur=[1,0,…,0,1]cur=[1,0,…,0,1],长度为当前行数
从curcur第二个元素到倒数第二个元素,利用动态规划:cur[j]=dp[j-1]+dp[j]cur[j]=dp[j−1]+dp[j]
将dpdp更新为cur
返回dp
python:
class Solution:
def getRow(self, rowIndex: int) -> List[int]:
if(rowIndex==0):
return [1]
dp=[1,1]
for i in range(3,rowIndex+2):
cur=[0]*(i)
cur[0]=cur[-1]=1
for j in range(1,i-1):
cur[j]=dp[j-1]+dp[j]
dp=cur
return dp
2.数学方法 公式
第n行第k列的值,可以通过通项公式:**C(n,k)=(n)!/(k)!(n-k)!**计算得到
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> a;
a.push_back(1);
for(int i=1;i<=rowIndex;i++)
{
__int128_t b=(fabo(rowIndex)/(fabo(i)*fabo(rowIndex-i)));
a.push_back(b);
}
return a;
}
__int128_t fabo(int num) //求阶乘 注意返回值类型
{
if(num<2) return 1;
else
{
return num*fabo(num-1);
}
}
};
注意用int,long long在测试中都超范围,最终用__int128_t通过
一定注意范围。
可优化:
C(n,k)=C(n,k-1)*(n-k+1)/k;
则每一个数都与前一个数相关,不需要每次都将全部求出,只需用一个变量保存前面已经乘过,求出的即可。也就不需要求阶乘函数
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> a;
a.push_back(1);
long pre=1;
for(int i=1;i<=rowIndex;i++)
{
long cur=pre*(rowIndex-i+1)/i;
a.push_back(cur);
pre=cur;
}
return a;
}
};
3.118基础上索引
vector<int> getRow(int rowIndex) {
vector<vector<int>> a(rowIndex+1);
for(int i=0;i<=rowIndex;i++)
{
for(int j=0;j<=i;j++)
{
if(j==0||j==i)
{
a[i].push_back(1);
}
else
{
a[i].push_back(a[i-1][j-1]+a[i-1][j]);
}
}
}
return a[rowIndex];
}