[Leetcode] Pascal's Triangle 杨辉三角形

java 4 2016-02-29 13:03
女装

Pascal's Triangle I

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]
]

迭代法

复杂度

时间 O(N) 空间 O(k^2)

思路

简单的按照杨辉三角形的规则计算就行了。

代码

public class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(numRows <= 0) return res;
        List<Integer> one = new ArrayList<Integer>();
        one.add(1);
        res.add(one);
        for(int i = 1; i < numRows; i++){
            List<Integer> line = new ArrayList<Integer>();
            // 加入第一个1
            line.add(1);
            // 加入中间的数
            for(int j = 1; j < i; j++){
                line.add(res.get(i-1).get(j-1) + res.get(i-1).get(j));
            }
            // 加入最后一个1
            line.add(1);
            res.add(line);
        }
        return res;
    }
}

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?

逆序相加法

复杂度

时间 O(N) 空间 O(k)

思路

同样用迭代的方法,根据上一层的值算下一层,不过这里每一层都在同一个List上操作。如果我们从后向前计算,而且每次计算都用到上一个位置的数的话,我们会重复计算好几次,导致结果错误。这里的技巧在于从后向前计算,并且每次计算用当前位置的值和上一位置的值,来更新当前位置的值。最后再在后面加个1,就是这一层的结果了。

代码

public class Solution {
    public List<Integer> getRow(int k) {
        List<Integer> line = new ArrayList<Integer>();
        // 加入第一个1
        line.add(1);
        if(k <= 0) return line;
        for(int i = 1; i <= k; i++){
            // 计算j+1位置的值,是根据j位置的值和j+1位置的值得到的,相当于往后位移一位
            for(int j = line.size() - 2; j >= 0; j--){
                line.set(j + 1, line.get(j) + line.get(j + 1));
            }
            // 加上最后一个1
            line.add(1);
        }
        return line;
    }
}

公式法

复杂度

时间 O(K) 空间 O(1)

思路

更“暴力”的方法,是直接使用公式,对于第k(k>=1)层下标为i(i>=0)的位置,数字应该为num[i-1] * (k - i) / i,由于这个乘法可能溢出,我们用一个long型临时变量将其存起来。

注意

rowIndex是0开始的,公式中k是1开始的

代码

public class Solution {
    public List<Integer> getRow(int rowIndex) {
        // rowIndex是0开始的,我们将它加1,得到k
        int k = rowIndex + 1;
        ArrayList<Integer> line = new ArrayList<Integer>();
        line.add(1);
        long tmp = 1;
        for(int i = 1; i < k; i++){
            // 使用公式 上一个数乘以(k-i)再除以i
            tmp = tmp * (k - i) / i;
            line.add((int)tmp);
        }
        return line;
    }
}
女装
文章评论