帕斯卡(杨辉)三角形问题

118Pascal’s Triangle—找规律迭代

问题描述:

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

问题解析:

1. 此题意思是给出一个行数row,给出杨辉三角的前row行的数。
2. 观察杨辉三角形,除了最左边和最右边的数,中间的第i个元素等于上一行的第i-1个和第i个元素之和


代码如下:

class Solution {
public:
    vector<vector<int>> generate(int numRows) 
    {
        vector<vector<int>> out;
        if(numRows < 1)
            return out;
        vector<int> res;
        res.push_back(1);
        out.push_back(res);
        // 如果输出一行
        if(numRows == 1 )
            return out;
        res.push_back(1);
        out.push_back(res);
        // 如果输出两行
        if(numRows == 2)
            return out;
        res.pop_back();
        int temp = 0;
        // 输出大于2行
        for(int i=3; i<=numRows; ++i)
        {
            for(int j=1; j<i-1; ++j)
            {
                temp = out.back()[j-1] + out.back()[j];
                res.push_back(temp);
            }
            res.push_back(1);
            out.push_back(res);
            res.clear();
            res.push_back(1);
            
        }
        return out;   
    }
};

119Pascal’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?

题目解析:

1. 此题与上一题稍有不同,求的是给定的某一行的杨慧三角行,而不是前n行的所有数。
2. 依旧利用杨辉三角形,除了最左边和最右边的数,中间的第i个元素等于上一行的第i-1个和第i个元素之和。
3. 可知杨辉三角第row行的数的个数就是row个,这次定义的辅助空间直接定义为O(row),然后从第一行开始不断更新这个辅助空间,即可得到第row行的所有数。
4. 需要注意的是:因为所有行共享一个辅助内存,所以相当于计算后面的数需要用到上一行也就是数组前面的数,所以每行的更新应该从最后一个更新至第一个,倒着更新。

代码如下:

class Solution {
public:
    vector<int> getRow(int rowIndex)
    {
        ++rowIndex;
        vector<int> res(rowIndex, 0);
        if(rowIndex < 1)
            return res;
        res[0] = 1;
        if(rowIndex == 1 )
            return res;
        res[1] = 1;
        if(rowIndex == 2)
            return res;
        int temp = 0;
        for(int i=3; i<=rowIndex; ++i)
        {
            // 注意,因为更新后面的数用到前面的数,所以倒着更新数组,保证正确性
            for(int j=i-2; j>=1; --j)
            {
                temp = res[j-1] + res[j];
                res[j] = temp;
            }
            res[i-1] = 1; 
        }
        return res;     
    }
};

120Triangle—求最三角形中短路径

问题描述:

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

问题解析:

1. 此题的意思是从三角形第一行开始,走到最后一行,求出每行经过数的最小和。并且下一行只能在上一行对应索引的以及下一个位置选值。

2. 此题利用动态规划最为简单。假设有辅助数组dp,里面带面到达当前行各位置的最小路径值。则当前第i位置的值,一定是上一行对应第i个位置和第i+1个位置中小的值加上本行第i个值,就是到达本行第i个位置的最小值。

3. 依旧利用动态规划定义一个一维数组,然后计算到达每行最小值时,都去更新这个数组

4. 注意依然是倒着更新数组,因为更新数组后面的数需要用到前面的数。

代码如下:

class Solution {
public:
    // 利用动态规划来做,需要注意,因为采用一维数组,所以每行的数字都必须倒着填
    int minimumTotal(vector<vector<int>>& triangle) 
    {
        if(triangle.empty())
            return 0;
        int size = triangle.size();
        // 创建辅助数组
        vector<int> dp(size, 0);
        // 初始化第一个数字
        dp[0] = triangle[0][0];
        // 依次填充剩余各行
        for(int i=1; i<size; ++i)
        {
            dp[i] = dp[i-1] + triangle[i][i];
            for(int j=i-1; j>=1; --j)
            {
                dp[j] = dp[j-1] < dp[j] ? dp[j-1]+triangle[i][j] : dp[j]+triangle[i][j];
            }
            dp[0] = dp[0] + triangle[i][0];
        }
        // 寻找最小的路径
        int res = -100000;
        for(int i=0; i<size; ++i)
        {
            if(res == -100000 || dp[i] < res) 
                res = dp[i];
        }
        return res;
    }
};
    原文作者:杨辉三角问题
    原文地址: https://blog.csdn.net/baidu_33604078/article/details/79145151
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞