118. Pascal’s Triangle—找规律迭代
问题描述:
Given numRows, generate the first numRows of Pascal’s triangle.
For example, given numRows = 5,
Return
[ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ]
问题解析:
1. 此题意思是给出一个行数row,给出杨辉三角的前row行的数。
2. 观察杨辉三角形,除了最左边和最右边的数,中间的第i个元素等于上一行的第i-1个和第i个元素之和。
代码如下:
class Solution {
public:
vector<vector<int>> generate(int numRows)
{
vector<vector<int>> out;
if(numRows < 1)
return out;
vector<int> res;
res.push_back(1);
out.push_back(res);
// 如果输出一行
if(numRows == 1 )
return out;
res.push_back(1);
out.push_back(res);
// 如果输出两行
if(numRows == 2)
return out;
res.pop_back();
int temp = 0;
// 输出大于2行
for(int i=3; i<=numRows; ++i)
{
for(int j=1; j<i-1; ++j)
{
temp = out.back()[j-1] + out.back()[j];
res.push_back(temp);
}
res.push_back(1);
out.push_back(res);
res.clear();
res.push_back(1);
}
return out;
}
};
119. Pascal’s Triangle II—依旧规律迭代来做
题目描述:
Given an index k, return the kth row of the Pascal’s triangle.
For example, given k = 3,
Return [1,3,3,1]
.
Note:
Could you optimize your algorithm to use only O(k) extra space?
题目解析:
1. 此题与上一题稍有不同,求的是给定的某一行的杨慧三角行,而不是前n行的所有数。
2. 依旧利用杨辉三角形,除了最左边和最右边的数,中间的第i个元素等于上一行的第i-1个和第i个元素之和。
3. 可知杨辉三角第row行的数的个数就是row个,这次定义的辅助空间直接定义为O(row),然后从第一行开始不断更新这个辅助空间,即可得到第row行的所有数。
4. 需要注意的是:因为所有行共享一个辅助内存,所以相当于计算后面的数需要用到上一行也就是数组前面的数,所以每行的更新应该从最后一个更新至第一个,倒着更新。
代码如下:
class Solution {
public:
vector<int> getRow(int rowIndex)
{
++rowIndex;
vector<int> res(rowIndex, 0);
if(rowIndex < 1)
return res;
res[0] = 1;
if(rowIndex == 1 )
return res;
res[1] = 1;
if(rowIndex == 2)
return res;
int temp = 0;
for(int i=3; i<=rowIndex; ++i)
{
// 注意,因为更新后面的数用到前面的数,所以倒着更新数组,保证正确性
for(int j=i-2; j>=1; --j)
{
temp = res[j-1] + res[j];
res[j] = temp;
}
res[i-1] = 1;
}
return res;
}
};
120. Triangle—求最三角形中短路径
问题描述:
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
The minimum path sum from top to bottom is 11
(i.e., 2 + 3 + 5 + 1 = 11).
问题解析:
1. 此题的意思是从三角形第一行开始,走到最后一行,求出每行经过数的最小和。并且下一行只能在上一行对应索引的以及下一个位置选值。
2. 此题利用动态规划最为简单。假设有辅助数组dp,里面带面到达当前行各位置的最小路径值。则当前第i位置的值,一定是上一行对应第i个位置和第i+1个位置中小的值加上本行第i个值,就是到达本行第i个位置的最小值。
3. 依旧利用动态规划定义一个一维数组,然后计算到达每行最小值时,都去更新这个数组。
4. 注意依然是倒着更新数组,因为更新数组后面的数需要用到前面的数。
代码如下:
class Solution {
public:
// 利用动态规划来做,需要注意,因为采用一维数组,所以每行的数字都必须倒着填
int minimumTotal(vector<vector<int>>& triangle)
{
if(triangle.empty())
return 0;
int size = triangle.size();
// 创建辅助数组
vector<int> dp(size, 0);
// 初始化第一个数字
dp[0] = triangle[0][0];
// 依次填充剩余各行
for(int i=1; i<size; ++i)
{
dp[i] = dp[i-1] + triangle[i][i];
for(int j=i-1; j>=1; --j)
{
dp[j] = dp[j-1] < dp[j] ? dp[j-1]+triangle[i][j] : dp[j]+triangle[i][j];
}
dp[0] = dp[0] + triangle[i][0];
}
// 寻找最小的路径
int res = -100000;
for(int i=0; i<size; ++i)
{
if(res == -100000 || dp[i] < res)
res = dp[i];
}
return res;
}
};