买股票的最佳时机 - 1

今天讲解买股票的最佳时机和买股票的最佳时机2。下面仅代表我自己的想法和思路,有错误请留言

买股票的最佳时机:

题目链接:121. 买卖股票的最佳时机 - 力扣(LeetCode)

题目:

 

提示:

  • 1 <= prices.length <= 100000
  • 0 <= prices[i] <= 10000

 下面我将通过 [7,1,5,3,6,4] 事例和大家进行讲解这道题的思路,首先先通过这些数据画一张折现图

 

通过这张图片上大家可以很清晰的看到,如果是我们想获得最大利润,而且在只购买一次的情况下,必须买的时候必须买最便宜的,然后找到后面最大的股票价钱,这样才可以达到购买的最大利润

根据图我们可以看到当在第一天买入时和在第四天卖出时,递增差值最大,这是获得最大利润最多

代码思路:

我们需要两个变量来存储我们的股票的最小价钱和我们获得的最大利润 ,然后通过遍历我们的prices就是给的数据,然后进行最大利润和最小股票价格的更新,

通过上面的数据大小和范围提示,0 <= prices[i] <= 10000,我们可以将最小价值设为10000,这样最小价值就可以根据数据进行更新了,(不会出现当股票的价钱都是10000时,然后我们将股票的最小价格设为9999时,这样还可以赚一块钱,事实上是不会赚钱的,最大利润应该为0)然后我们的最小利润就是0,迭代时我们需要保留当前股票下的最大利润和该股票之前的股票最小价值,当前的最大利润就是上一个股票的最大利润和当前股票减去股票的最小价值的值,最后得到的利润就是我们的最大利润

 代码:
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = 10000;
        int minPrice = n;
        int maxProfit = 0;
        for (int i = 0; i < prices.size(); i++) {
            maxProfit = max(maxProfit, prices[i] - minPrice);
            minPrice = min(minPrice, prices[i]);
        }
        return maxProfit;
    }
};

买股票的最佳时机2:

题目链接:122. 买卖股票的最佳时机 II - 力扣(LeetCode)

 题目:

  • 1 <= prices.length <= 30000
  • 0 <= prices[i] <= 10000

这个题和上个题的区别就是这个可以多次购买,上面的只能购买一次,虽然可以多次购买,但是不能卖出的同时再买入,就是比如在第二天卖出了,就不能在第二天买入了,只能在第二天以后买入了,通过判断分析可知,当我们在第一天买入,第二天卖出,然后在第三天买入,第四天,卖出,就可以获得最大利润,这道题有两个解法,一个是贪心,一个是动态规划,

 

贪心:

因为题目要求我们获得最大利润,所以我们只在股票价格上升的时候加到我们的利润当中,这样就可以获得最大利润

 贪心代码:
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int res = 0;
        for (int i = 1; i < prices.size(); i++) {
            if ((prices[i] - prices[i - 1]) < 0) {
                continue;
            } else {
                res += (prices[i] - prices[i - 1]);
            }
        }
        return res;
    }
};
动态规划:

我们需要存储两个状态,就是当我们手里面没有股票和当我们的身上有股票,然后遍历prices数据,不断更新当前股票的没有持有股票的最大价格,和持有股票的最大价格,

没有持有股票的最大价格是前一个股票的没有持有股票的最大利润和前一个持有股票但是在该股票卖出的最大值

持有股票的最大价格是前一个股票的持有股票的最大利润和不持有股票但是在该股票买入的最大值

最后的没有股票的利润就是我们要的最大利润

 动态规划:
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //  表示不持有股票时的最大利润,初始值为 0。
        int cash = 0;
        //  表示持有股票时的最大利润,初始值为
        //  -prices[0](表示第一天买入股票)。
        int hold = -prices[0];
        for (int i = 1; i < prices.size(); i++) {
            int prev_cash = cash;
            // 取前一天的 cash 和前一天的 hold 加上当天的价格(卖出股票)的较大值
            cash = max(cash, hold + prices[i]);
            // 取前一天的 hold 和前一天的 cash 减去当天的价格(买入股票)的较大值。
            hold = max(hold, prev_cash - prices[i]);
        }
        return cash;
    }
};