给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
- 示例:
输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
我的方案
思路
杨辉三角显然是上一行相对的左元素和右元素之和,那么循环到每一行加上上一行这两个值即可。这个题是属于动态规划的范畴,我这里没有使用临时空间存储上一行的元素,只是每次循环时临时查询出来计算,所以应该不属于动态规划的算法(待议)
算法
先明确边界条件,然后将单独的1放入集合。从第二行开始循环,除第一个和最后一个位置置为1,将上一行本位置-1和相对于本位置的数值相加存放到整型集合。
代码
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> lists = new LinkedList<List<Integer>>();
List<Integer> list1 = new LinkedList<Integer>();
if(numRows==0){
return lists;
}
list1.add(1);
lists.add(list1);
for(int i =1;i<numRows;i++){//从第二行开始
List<Integer> list = new LinkedList<Integer>();
list.add(1);
list.add(1);
for(int k =1;k<i;k++){
int num = lists.get(i-1).get(k-1)+lists.get(i-1).get(k);
list.add(k,num);
}
lists.add(list);
}
return lists;
}
}
复杂度分析
- 时间复杂度:O(n^2)
- 空间复杂度:O(n)
官方方案
思路
如果能够知道一行杨辉三角,我们就可以根据每对相邻的值轻松地计算出它的下一行。
算法
虽然这一算法非常简单,但用于构造杨辉三角的迭代方法可以归类为动态规划,因为我们需要基于前一行来构造每一行。
首先,我们会生成整个 triangle 列表,三角形的每一行都以子列表的形式存储。然后,我们会检查行数为 0 的特殊情况,否则我们会返回 [1]。如果numRows>0,那么我们用 [1] 作为第一行来初始化 triangle with [1]。
代码
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> triangle = new ArrayList<List<Integer>>();
// First base case; if user requests zero rows, they get zero rows.
if (numRows == 0) {
return triangle;
}
// Second base case; first row is always [1].
triangle.add(new ArrayList<>());
triangle.get(0).add(1);
for (int rowNum = 1; rowNum < numRows; rowNum++) {
List<Integer> row = new ArrayList<>();
List<Integer> prevRow = triangle.get(rowNum-1);
// The first row element is always 1.
row.add(1);
// Each triangle element (other than the first and last of each row)
// is equal to the sum of the elements above-and-to-the-left and
// above-and-to-the-right.
for (int j = 1; j < rowNum; j++) {
row.add(prevRow.get(j-1) + prevRow.get(j));
}
// The last row element is always 1.
row.add(1);
triangle.add(row);
}
return triangle;
}
}
复杂度分析
- 时间复杂度:O(numRows^2)
外层循环需要运行
numRowsnumRows 次,但在外层循环的每次迭代中,内层
循环要运行 rowNumrowNum 次。 - 空间复杂度:O(numRows^2)
因为我们需要存储我们在 triangle 中更新的每个数字,
所以空间需求与时间复杂度相同。