算法分析与设计第一周121.Best Time to Buy and Sell Stock&122. Best Time to Buy and Sell Stock II
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法分析与设计第一周121.Best Time to Buy and Sell Stock&122. Best Time to Buy and Sell Stock II相关的知识,希望对你有一定的参考价值。
原题来自:121:https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
122:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/
第一周,小试牛刀吧。
题目121不复杂,就是英文原题读起来怪怪的。意思是,在保证先买后卖且最多只能买卖一次的情况下,计算最大利润。
思路很简单:逐个求差,差最大且被减数的下标大于减数的下标就可以了。最简单暴力的方法是用两重循环:
int maxProfit(int* prices, int pricesSize) { int max = 0; for (int i = 0; i < pricesSize; i++) { for (int j = i; j < pricesSize; j++) { if (prices[j] - prices[i] > max) { max = prices[j] - prices[i]; } } } return max; }
显然,此算法的时间复杂度为0(n^2)。根据leetcode给出的分析图,虽然AC,我的方法还有很大的优化空间。
优化的话,思路本质上还是一样的。就是求一个峰值和谷底值之差,且峰值在谷底值后面。主要是能否想到一个巧妙的方法避开双重循环,目前还没想好。
--------------------------------------------------
做完121,发现还有升级版122。122的意思是,在保证先买后卖且在一个买卖周期内最多只能买卖一次的情况下,计算最大利润。也就是说,卖出之后还可以再进行买入等操作。
这就很有意思了。在没有买卖次数限制的情况下,同样是获得最大利润,情况可以有多种。一开始我是懵的。第一反应是穷举,计算出所有能盈利的情况,再进行比较,得到最大利润。先不说这是个比较浩大的工程量,最重要的是我根本不知道这看似简单的方法从何下手(ˉ▽ˉ;)...。
后来观摩了一下讨论区,发现一位大牛的做法很有意思。大牛的思路很巧妙,就是逐个相减,差大于零就盈利,把盈利的部分加起来;差小于零就进入往后挪,继续相减。哇,简直神奇!把n天切割成n次买卖,每次在第i天买入,第i+1天卖出。只看上升的小段,叠加,忽略下降的小段。
举个简单的例子。对于一种情况{4, 1, 2, 3, 5}来说,最佳盈利策略应当是在1的时候买入,5的时候卖出,盈利为4,一手买卖即可。而按照上面的方法,将这一手买卖分解为1买2卖,2买3卖,3买5卖,共盈利4,三次买卖利润与前面的一手买卖利润一致,但是解释起来更加简便、清晰。
对于另一种情况{4, 1, 3, 2, 5}来说,两个峰,只看上升的小段,看起来就更加清楚了。
这种方法就相当于把长线买卖都简化成了“如果保证盈利,买了马上就卖”的小短线模式的叠加,与周五刚刚学过的“分治”思想还真有异曲同工之妙。
代码实现起来就很简单了:
int maxProfit(int* prices, int pricesSize) { int total = 0; for (int i=0; i< pricesSize-1; i++) { if (prices[i+1] > prices[i]) total += prices[i+1] - prices[i]; } return total; }
以上是关于算法分析与设计第一周121.Best Time to Buy and Sell Stock&122. Best Time to Buy and Sell Stock II的主要内容,如果未能解决你的问题,请参考以下文章
算法: 买卖股票的时间 121. Best Time to Buy and Sell Stock
121 Best Time to Buy and Sell Stock 买卖股票的最佳时机
121. Best Time to Buy and Sell Stock
Leetcode 121. Best Time to Buy and Sell Stock