LeetCode 121和122. 买卖股票的最佳时机

121.

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

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

示例 2:

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

提示:

  • 1 <= prices.length <= 105
  • 0 <= prices[i] <= 104

122.

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。返回 你能获得的 最大 利润 。

示例 1:

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

示例 2:

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

示例 3:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。

提示:

  • 1 <= prices.length <= 3 * 104
  • 0 <= prices[i] <= 104

121题的思路:注意,整个周期内,股价最高点可能在股价最低点的左边,这个差价是无法获得的,我们只能想办法找到某个最大的上涨周期,这个周期也可能不是一直涨,而是有涨有跌,总体向上。

如上图所示,很明显可以看出,应该在两个蓝色横线处买卖。整个周期内最低点是绿色划线处,但无法操作获取最大值,黄色划线处虽然是从低点上涨的小周期最大点,但不是整个周期最大点。

所以,我们的算法就是从prices[0]开始遍历,找到这段时期股票的最小值的日期i,设置股票最小值minprice = prices[i]; 就是上图左边蓝色划线处的点。

那么怎么样才能收益最大呢?那就是往后遍历到某个日期i,这个日期i的股票值是从上一步最低价到现在这个周期里最高的价格的点,这段时间,股票都是上涨的,prices[i] - minprice就是当前这个上涨时间段里面的最大利润,设置为maxprofit。

继续遍历,上一步之后股价下跌或横盘了,就开始找新的最低价和最高价,如果有股价更低的点时,更新minprice,比如说上图绿色的点的值。

当后续还有上涨的情况时,找到新的最高价的点i,求出这个时间段的最大利润prices[i] - minprice,比较这个利润与之前所有上涨期内的记录下的最大的那个利润值maxprofit,让maxprofit等于这两个值中的最大那个值。

重复上面步骤直到遍历完成。

注意,因为在for循环中找最低点和最高点时,用的都是变量i,是先找到最低值,再找最高值,不会出现先卖后买的情况。
public class Solution {
    public int maxProfit(int prices[]) {
        int minprice = Integer.MAX_VALUE;
        int maxprofit = 0;
        for (int i = 0; i < prices.length; i++) {
            if (prices[i] < minprice) {
                minprice = prices[i];
            } else if (prices[i] - minprice > maxprofit) {
                maxprofit = prices[i] - minprice;
            }
        }
        return maxprofit;
    }
}

122题的思路

只要第二天上涨那就今天买,明天卖,在所有上涨的周期内都进行买卖操作,在下跌和横盘的时候不操作即可。

和上一题都注意股票没有开盘或者只有一天有值的情况,直接就返回0。

其实这里有个问题,现实中是无法预测第二天涨跌的,所以不存在每次最低点买,最高点卖。但是题目给的示例结果显示的是知道所有的涨跌了,那就这样计算。

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        int buyTime = 0;
        int sellTime = 1;
        int [] profit = {0};
        if (n <= 1){
            return 0;
        }
        for (int i = 0; i < n - 1; i++){
            if (prices[i] <= prices[i + 1]) {
                profit[0] += prices[i + 1] - prices[i];
            }
        }
        return profit[0];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值