初识Leetcode----学习(十四)【杨辉三角、买卖股票的最佳时机】

杨辉三角

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

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

示例:

输入: 5
输出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

杨辉三角的性质:

  1. 杨辉三角以正整数构成,数字左右对称,每行由1开始逐渐变大,然后变小,回到1。
  2. n行的数字个数为n个。
  3. n行的第k个数字为组合数C_{n-1}^{k-1}
  4. n行数字和为2^{n-1}
  5. 除每行最左侧与最右侧的数字以外,每个数字等于它的左上方与右上方两个数字之和(也就是说,第n行第k个数字等于第n-1行的第k-1个数字与第k个数字的和)。这是因为有组合恒等式:C_{n}^{i}=C_{n-1}^{i-1}+C_{n-1}^{i}。可用此性质写出整个杨辉三角形。

1.用两层循环,利用杨辉三角的性质(每一层除首尾外其他元素都为上一层的两个元素之和,即a[i][j] = a[i-1][j-1] + a[i - 1][j]),可以将其类比为二维数组,逐行插入数据得出结果:

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> vec(numRows);   ///定义一个目标容器保存结果
        if(numRows <= 0)  return vec;       //如果传入的numRows小于等于0,则返回空容器
        for (int i = 0; i < numRows; ++i)   //外层循环,对所有行进行操作
        {
            vec[i].push_back(1);            //将每一行的首元素置1
            for (int j = 0; j < i; ++j)     //内层循环,对行内每个元素操作
            {
                f (i > j && j != 0)        //如果不是首元素并且j不等于0(等于0则j-1越界),将上层两个元素之后插入该层位置
                    vec[i].push_back(vec[i-1][j] + vec[i - 1][j-1]);
            }
            if (i > 0)
               vec[i].push_back(1);     //如果不是第一行,则添加尾元素
        }
        return vec;
    }
};

杨辉三角Ⅱ

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

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

示例:

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

进阶:

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

1.使用上一题的思路,将每一层的数据存入容器中,最后返回需要的那一行的数据:

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<vector<int>> vec(rowIndex + 1);   //创建存储所有数据的容器
        if (rowIndex < 0)  return vec[0];     //如果输入的行数小于0,返回空
        if(rowIndex == 0)  return {1};       //输入第0行,则返回1
        for (int i = 0; i <= rowIndex; ++i)   //此处与上一题一致
        {
            vec[i].push_back(1);
            for (int j = 0; j < i; ++j)
            {
                if (i > j && j != 0)
                    vec[i].push_back(vec[i-1][j] + vec[i - 1][j-1]);
            }
            if (i > 0)
               vec[i].push_back(1);
        }
        return vec[rowIndex];     //返回所需的那一行
    }
};

2.利用杨辉三角的性质,需要两个for循环,除了第一个数为1之外,后面的数都是上一次循环的数值加上它前面位置的数值之和,不停地更新每一个位置的值,便可以得到第n行的数字:

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> vec(rowIndex + 1);
        if (rowIndex < 0) return vec;
        for (int i = 0; i <= rowIndex; ++i) {
            if ( i == 0) {    //当为第0行时,数值为1
                vec[0] = 1;
                continue;
            }
            for (int j = rowIndex; j >= 1; --j) {  //每一行的数据(由上一行得出)
                vec[j] = vec[j] + vec[j-1];
            }
        }
        return vec;
    }
};

买卖股票的最佳时机

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

1.用一个变量记录遍历过程中的最小值,然后每次计算当前值和这个最小值之间的差值,更新该最大差值,当遍历完成后得出最大利润:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty() || prices.size() == 1)
            return 0;
        int res = 0, buy = INT_MAX;
        for (int price : prices)
        {
            buy = min(buy, price);     //遍历得出最小值
            res = max(res, price - buy);  //更新最大差值
        }
        return res;
    }
};

买卖股票的最佳时机Ⅱ

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

示例 2:

输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

1.因为可以多次买入与卖出,所以只要第二天的股票价格比当天价格高,就可以在当天买入,第二天卖出,并将其加入差值,计算利润:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int res = 0, n= prices.size() - 1;
        for (int i = 0;i < n; ++i)
        {
            if (prices[i] < prices[i + 1])   //如果第二天股票价格高于当天价格
                res += prices[i+1] - prices[i];  //则计算其差值加入利润
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/83186252