05 August 2008
Given a non-negative integer numRows, generate the first numRows of Pascal’s triangle.
In Pascal’s triangle, each number is the sum of the two numbers directly above it.
Example:
1
2
3
4
5
6
7
8
9
Input: 5
Output:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
这道题输入是一个层数,要求输出帕斯卡三角的所有层,由一个二维数组来表示。思路很直接,每一层都用一个array来保存前一层的指针,当前行的数据由前一层来得到,每一层的每个元素由前一层的两个邻接元素相加;每一层的第一个和最后一个元素都是1。
Time: O(1+2+3+…+n)=O(n^2);Space:一个二维数组来存最后的三角形,存前一层的指针和当前层只是一维数组,因此是O(n^2)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (numRows <= 0) {
return result;
}
ArrayList<Integer> previousRow = new ArrayList<>();
previousRow.add(1);//第一行只有一个数,先加上
result.add(previousRow);
for (int i = 1; i <= numRows - 1; i++) {//从第二行开始有“前一行”
ArrayList<Integer> currentRow = new ArrayList<>();//新建一个array存当前行,当前行比前一行多两个元素
currentRow.add(1);//当前行的第一个元素为1,每一轮更新的时候上一轮的1会成为最右边的那个1
for (int j = 0; j < previousRow.size() - 1; j++) {//从上一行的第一个元素到最后一个元素都会参与计算
currentRow.add(previousRow.get(j) + previousRow.get(j+1));//前一行相邻两个元素相加,比如当前行的第2个元素就是上一行第0个和第1个相加,下一道题可以优化这里
}
currentRow.add(1);//当前行最后一个元素是1
result.add(currentRow);
previousRow = currentRow;
}
return result;
}
}
另外一种写法是在每一行生成时,在该行index 0的位置加入1,然后根据在2行以后根据上一行的元素推断出当前行的元素的值,更加清晰明了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (numRows <= 0) {
return result;
}
ArrayList<Integer> currentRow = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
currentRow.add(0, 1);
for (int j = 1; j < currentRow.size() - 1; j++) {//“掐头去尾”,头尾两个数都是1,中间的数才需要计算
currentRow.set(j, currentRow.get(j) + currentRow.get(j+1)); //在当前行从j位置开始更新
}
ArrayList<Integer> copyRow = new ArrayList<Integer>(currentRow);//这里直接add currentRow的话,当currentRow下一轮变化时会影响result里面的值
result.add(copyRow);
}
return result;
}
}
尾递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public List<List<Integer>> generate(int numRows) {
return generateHelper(new ArrayList<List<Integer>>(), numRows);
}
private List<List<Integer>> generateHelper(List<List<Integer>> triangle, int numRows) {
if (numRows == 0) { // 基线条件,需要创建的三角形行数
return triangle;
}
List<Integer> newList = new ArrayList<>(); // 新的一行
newList.add(1); // 每一行的第一个位置是1
if (triangle.size() != 0) { // 第一行加入的时候不用计算中间的值
List<Integer> lastList = triangle.get(triangle.size() - 1);
for (int i = 0; i < lastList.size() - 1; i++) {//没有包括最后一列
int current = lastList.get(i);
int next = lastList.get(i + 1);
newList.add(current + next); // 计算三角形的值
}
newList.add(1); //最后一列
}
triangle.add(newList); // 加入当前一行
return generateHelper(triangle, numRows - 1);
}
}