LeetCode-122-买卖股票的最佳时机 II


题意描述:

给定一个数组,它的第 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

解题思路:
Alice: 做完这题我们是不是就可以去买股票了,hhhh
Bob:不是,我们无法准确预测明天的股票价格,也不能穿越到前几天去买股票。
Alice: 你怎么这么直啊,难道我不知道么
Bob: 看题看题,-_-||
Alice: 题目里面有一句话 你不能同时参与多笔交易,什么意思呢?
Bob: 就是说你在一次买入之前必须保证你的账户里面是空的,也就是说在买入之后必须卖出了,才能再次买入。
Alice: 哦哦,是对现实股票市场的一种简化了。那我可以买入之后立即以同样的价格卖出啊,虽然不能获利。
Bob:是的,甚至你同一天多次重复这样的买入卖出也是可以的。再给你讲个笑话吧,如果你在美股市场上这样操作几次,美国的GDP就会增加了,hhhhh。
Alice:额 好吧。具体怎么操作呢 ?这应该是一道贪心算法的题目吧,只要能够获利就买入卖出,只要每次获利的机会都没有错过那就是最大获利了。
Bob: 呦吼,不错哦,反证法的味道,只要每次获利的机会都没有错误,那么加起来应该就是最大获益。
Alice: 还有一个疑问,怎么证明 我们的短线的 买入卖出 和 示例里面长线的买入卖出是等价的呢?
Bob: 举个例子吧,看[ 1 ,2, 3, 4, 5] 这个例子, 4 = 5 - 1 = 2 - 1 + 3 - 2 + 4 - 3 + 5 - 4
Alice: 这个例子是没有问题的,那像[2,1,3,2,5,1,5]这种更一般的例子呢。
Bob: 一样的呀,你想啊,对于任一的买入价格 in 和任一的卖出价格 out,只要这两者之间存在着一些中间值上面的式子都是成立的呀。profit = out - in = out - price[i] + price[i] - price[j] + price[j] - in其中 out > price[i] > price[j] > in
Alice: 哇,ヾ(゚д゚)ノ
Bob: O(∩_∩)O哈哈~


代码:

  • Python 方法一: 贪心
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) == 0:
            #数组长度是零的时候,没有任何交易,没有任何获益。
            return 0
        else:
            profits  = 0
            # 总的利润
            inPrice = prices[0]
            # 买入的价格
            for price in prices:
                # 只要一次操作能够获利就执行,大不了多次买入卖出而已,和执行步骤较少的方案获益一样的。
                if price > inPrice:
                    # 如果在之前有买入而且现在卖出可以获益,就卖出
                    profits += price - inPrice
                    inPrice = price
                    # 卖出的当天在以同样的价格买入
                if price < inPrice:
                    # 以前买入的价格太贵了,直接重新买入,可以理解为上次买入之后直接卖出。
                    inPrice = price
            return profits

Java 方法一:还是贪心

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length == 0){
            return 0;
        }else{
            int inPrice = prices[0];
            int profits  = 0;
            for(int i=0; i<prices.length; ++i){
                if(prices[i] > inPrice){
                    profits += prices[i] - inPrice;
                    inPrice  = prices[i]; 
                }
                if(prices[i] < inPrice){
                    inPrice = prices[i];
                }
            }
            return profits;
        }
    }
}
  • c++ 方法一: 贪心,加一些优化。可以认为我们的钱是无限多的,每天的股票都买入,如果第二天的价格高于昨天的价格就在第一天买入第二天卖出,否则就在第一天买入第一天卖出。这样所有的买入卖出操作都是不赔钱的,而所有获利的时机我们都没有错过。
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.empty()){
            return 0;
        }else{
            int inPrice = prices[0];
            int profits = 0;
            for(int i=0; i<prices.size(); ++i){
                if(prices[i] > inPrice){
                    profits += prices[i] - inPrice;
                }
                inPrice = prices[i];
            }
            return profits;
        }
    }
};

Python 方法一:上述所有版本的最终简化版,只是可能会不太好理解。😂

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) <= 1:
            return 0
        else:
            profits = 0
            for x in range(1, len(prices)):
                if prices[x] - prices[x-1] > 0:
                    profits += prices[x] - prices[x-1]
            return profits

易错点:

  • 一些测试样例
[]
[7,1,5,3,6,4]
[1,2,3,4,5]
[7,6,4,3,1]
[2,1,3,2,5,1,5]
  • 答案
0
7
4
0
9

总结:

Java 真的很快诶。。。
在这里插入图片描述


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值