Pascal's Triangle II

来源:互联网 发布:淘宝联盟微信推广技巧 编辑:程序博客网 时间:2024/06/13 03:31

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?


Pascal的定义可以知道第一行是一个1, 以后每行都可以有上一行的两个元素相加而得,如果我们这样来看
1
11
121
1331
。。。。

可以得到这样一个公式, 即每一个元素的值都自己头顶上的元素以及之前的一个元素之和: cur[i] = pre[i] + pre[i - 1]
由此可以直接得到下边的第二个方法,用两个数组来交替表示当前行和上一行,然后用上一行的值来算出当前行的值,时间复杂度是n*n, 空间复杂度是2*n.

时间复杂度上来说,除非用直接表示第n行的数学公式来算低n行的值,总是要n*n的复杂度; 那么空间复杂度呢? 是不是2*n就是最好的呢(以及比native的n*n小很多了)? 答案是肯定的,实际上从上边的公式可以看出,当前行的每一个元素都是只和上一行的两个元素有关,如果我们从后向前计算当前行的值,则可以直接在一个数组上完成计算,详见下边的方法1的代码。 

Note:返回值用move来减少一次vector copy的消耗,可以参见C++11的right value以及move forward相关概念。


class Solution {public:    vector<int> getRow(int rowIndex) {        if (rowIndex < 0) {            throw new invalid_argument("Index must not be negative");        }                // 1                vector<int> ret(rowIndex + 1, 1);        for (int i = 3; i <= rowIndex + 1; ++i) {            for (int j = i - 2; j > 0; --j) {                ret[j] += ret[j - 1];            }        }        return move(ret);                        // 2        /*        vector<vector<int>> ret(2, vector<int>());        int pre = 0, cur = 1;        for (int i = 0; i <= rowIndex; ++i) {            ret[cur].assign(i + 1, 1);            for (int j = 1; j < i; ++j) {                ret[cur][j] = ret[pre][j] + ret[pre][j - 1];            }            swap(pre, cur);        }                        return move(ret[pre]);        */    }};


0 0