Leetcode(W8):121. Best Time to Buy and Sell Stock(动态规划)

leetcode中Best Time to Buy and Sell Stock买卖股票的最佳时间总共有5道类型题。


1. Best Time to Buy and Sell Stock

介绍:

Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

题意:

给定一个数组,下标代表第几天,元素值即为当天可买进或卖出的股票价格,现在设定我们最多只能进行一次交易(即一次买一次卖,后面的题目会在这个条件做各种变化),谋取最大利益然后输出这个最大利益。

举例:

Input: [7, 1, 5, 3, 6, 4]
Output: 5
第二天的1块钱买进,第五天6块钱卖出,赚5。
例2:
Input: [7, 6, 4, 3, 1]
Output: 0
股票一路下跌,所以只能当天买当天卖,赚0。

思路:

最暴力的版本就是直接枚举所有可能的情况分析了,即两重循环,第i天买进,第j天卖出,然后i从第一个元素遍历到最后一个元素,j从i遍历到最后一个元素,每次计算array[j]-array[i]的值,最后挑一个最大的保存。
然而不难发现这种算法有很多多余的计算,比如如果你已经算过买入价格为3的卖出情况了,那么今天买入价格为5的还有必要算吗,所以算法其实能剪枝的地方还有很多。
这里要讲的是第二种方法,用动态规划,还是遍历数组,但是这次只需要一重循环。我们假设在第i天能赚到的最大利益为a[i-1],那么只需要计算出i到最后一天时的a[i]即可,很明显a[0]为0,a[1]为max(a[0],第二天作为卖出-(前两天的最小值)作为卖出),a[2]为max(a[1],第三天作为卖出-(前三天的最小值)作为卖出)……在后面的文章中会谈到一种算法,将这里所说的“第X天作为卖出-(前X天的最小值)作为卖出”作为一个新的数组,这样能方便计算当题目条件为“能进行K次交易”时的情景。

操作:

在一重循环中每输入一个第X天的股票值就与前面输入的所有股票值进行判断,于是得到一个前X天的最低股票值curmin。
然后在循环中计算array[i]-curmin的值,这个值是今天卖出所得利润,这个今天利润也要与前面的利润进行判断,于是得到我们在第X天能赚到的最大利润。
在最后一天所能赚到的最大利润即为结果。

2. 代码

暴力法

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int result = 0;
        for (int i = 0; i < prices.size(); i++) {
            for (int j = i+1; j < prices.size(); j++) {
                int temp = prices[j] - prices[i];
                if (temp > result) {
                    result = temp;
                }
            }
        }
        return result;
    }
};

动态规划法

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() < 2) return 0;
        int curmin = prices[0];
        int result = 0;
        for (int i = 0; i < prices.size(); i++) {
            curmin = min(curmin, prices[i]);
            result = max(result, prices[i] - curmin);
        }
        return result;
    } 
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值