杨辉三角【递推】

先看一眼杨辉三角是啥


杨辉三角

题目1:

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

示例:

输入: 5
输出:

[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]

class Solution {
    //给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
    public List> generate(int numRows) {
        List> triangle = new ArrayList>();
        
        for(int i=1; i<=numRows; i++){ //循环行数
            List list_row = new ArrayList();
            
            for(int j=1; j<=i; j++){ //每一行中循环列数(每一行的列数==行号)
                if(j==1 || j==i){
                    list_row.add(1); //两侧补1
                }else{
                    list_row.add(triangle.get(i-2).get(j-2) + triangle.get(i-2).get(j-1));  
                }
            }
            triangle.add(list_row);
        }
        return triangle;
    }
}

题目2:

给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。

示例:

输入: 3
输出: [1,3,3,1]

进阶:

你可以优化你的算法到 O(k) 空间复杂度吗?

class Solution {
    public List getRow(int rowIndex) {
        List row_up_temp = new ArrayList();
        
        for(int i=0; i<=rowIndex; i++){
            List row_cur = new ArrayList();
            
            for(int j=0; j<=i; j++){
                if(j==0 || j==i){
                    row_cur.add(1);
                }else{
                    row_cur.add(row_up_temp.get(j-1) + row_up_temp.get(j));
                }
            }
            
            row_up_temp = row_cur;
        }
        return row_up_temp;
    }
}

另一种解法,公式法



根据组合数的公式,将(n-k)!约掉,化简就是下边的结果。

Cnk=n! / (k!(n−k)!)=(n∗(n−1)∗(n−2)∗...(n−k+1))/k!

public List getRow(int rowIndex) {
    List ans = new ArrayList<>();
    int N = rowIndex;
    for (int k = 0; k <= N; k++) {
        ans.add(Combination(N, k));
    }
    return ans;
}
 
private int Combination(int N, int k) {
    long res = 1;
    for (int i = 1; i <= k; i++)
        res = res * (N - k + i) / i;
    return (int) res;
}

我们可以优化一下。
上边的算法对于每个组合数我们都重新求了一遍,但事实上前后的组合数其实是有联系的。
Cnk=Cnk-1​×(n−k+1)/k
代码的话,我们只需要用pre变量保存上一次的组合数结果。计算过程中,可能越界,所以用到了long。

public List getRow(int rowIndex) {
    List ans = new ArrayList<>();
    int N = rowIndex;
    long pre = 1;
    ans.add(1);
    for (int k = 1; k <= N; k++) {
        long cur = pre * (N - k + 1) / k;
        ans.add((int) cur);
        pre = cur;
    }
    return ans;
}

你可能感兴趣的:(杨辉三角【递推】)