LeetCode 119:杨辉三角 II

LeetCode 119:杨辉三角 II

题目描述

给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。
在这里插入图片描述

在杨辉三角中,每个数是它左上方和右上方的数的和。

【示例】

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

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

解题

数学法

    与杨辉三角I思路一致,直接计算,唯一的问题是行数过高时会超int范围,所以中间结果要先转换到更高的数据类型上。

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> vect(1,1);
        for (int i=1; i<=rowIndex; ++i)
            vect.emplace_back(static_cast<long long>(vect[i-1])*(rowIndex-i+1)/i);  //这里前两项相乘会超出int范围
        
        return vect;
    }
};

杨辉三角的特性

    与杨辉三角I思路一样,将杨辉三角左对齐发现:

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

a j i = a j i − 1 + a j − 1 i − 1 , j ≥ 1 , i ≥ 1 a_{j}^{i}=a_{j}^{i-1}+a_{j-1}^{i-1},j\ge 1,i\ge1 aji=aji1+aj1i1,j1,i1
    上一时刻数组总长比这一时刻小1,因此可以在上一时刻数组后面加个0,保证对齐,且可以直接从最右向左更新。

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> vect(1,1);
        for (int i=1; i<=rowIndex; ++i){
            vect.emplace_back(0);
            for (int j=i; j>=1; --j)
                vect[j] = vect[j]+vect[j-1];
        }
        return vect;
    }
};

    上下两段代码的基本思路是一样的,不同点在于更新的方式。下面这种方法在每次循环中构造当前行所对应的数组(多余的1除外)。比如输入为3,它的循环过程如下:

首先构造[1, 1, 1, 1]
第一次循环结果[1,2,1,1],最左边三个恰好是输入为2的结果[1,2,1]
第二次循环结果[1,3,3,1],得到目标结果。
算法要计算的实际上是除两端1之外的值,因此只有输入大于等于2时才会进入循环体。
假如输入为4,最开始构造[1,1,1,1,1]
第一次循环结果[1,2,1,1,1],最左边三个恰好是输入为2的结果[1,2,1]
第二次循环结果[1,3,3,1,1],最左边四个恰好是输入为3的结果[1,3,3,1]
最三次循环结果[1,4,6,4,1],得到目标解

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> vect(rowIndex+1,1);
        for (int i=2; i<=rowIndex; ++i){
            for (int j=i-1; j>=1; --j)
                vect[j] = vect[j]+vect[j-1];
        }
        return vect;
    }
};
迭代实现

    我们也可以使用迭代方式实现上述算法。

class Solution {
private:
    void getRow(int rowIndex, vector<int>&out){
        if (rowIndex<0) return;
        if (rowIndex==0) {
            out[0]=1;
            return;
        }
        getRow(rowIndex-1, out);
        for (int i=rowIndex; i>0; --i)
            out[i]+=out[i-1];
    }
public:
    vector<int> getRow(int rowIndex) {
        vector<int> out(rowIndex+1, 0);
        getRow(rowIndex, out);
        return out;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值