LintCode-买卖股票的最佳时机I、II、III

思路概述

I、只许购买一次股票。遍历所有时间的股票价格,以当前股票价格之前出现过的最低价作为买入价,并计算出当天价格出售的收益,与曾经的最大收益对比,遍历完即可的得到最大可能收益;
II、交易次数不限,但每次只能持有一只股票。就可以用贪心法,只要当天价格高于前一天,就加入到收益之中去;
III、最多两次购买股票。动态规划问题,可以以第i天未分界点,计算前面的单次股票最大收益和后面股票的最大收益,然后求两者和的最大值作为最终的收益。
IV、特殊的动态规划问题,Local[i][j]表示在到达第i天时最多可进行j次交易并且最后一次交易在最后一天卖出的最大利润,此为局部最优。Global[i][j]为在到达第i天时最多可进行j次交易的最大利润,此为全局最优。特别注意,递推公式的max函数实际上代表了对过去状态产生的多个结果进行择优。

特殊动态规划问题公式

Local[i][j] = max(Local[i-1][j], Global[i-1][j-1]) + difference(状态增益值)
Global[i][j] = max(Local[i][j], Global[i-1][j])
理解公式很重要。

I

描述

假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格。如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润。

样例

给出一个数组样例 [3,2,3,1,2], 返回 1

代码

class Solution:
    """
    @param prices: Given an integer array
    @return: Maximum profit
    """
    def maxProfit(self, prices):
        maxProfit = 0
        if len(prices) == 0:
            return maxProfit
        minPrice = prices[0]
        for i in range(1, len(prices)):
            minPrice = min(minPrice, prices[i])
            maxProfit = max(maxProfit, prices[i]-minPrice)
        return maxProfit

II

描述

假设有一个数组,它的第i个元素是一个给定的股票在第i天的价格。设计一个算法来找到最大的利润。你可以完成尽可能多的交易(多次买卖股票)。然而,你不能同时参与多个交易(你必须在再次购买前出售股票)。

样例

给出一个数组样例[2,1,2,0,1], 返回 2

代码

class Solution:
    """
    @param prices: Given an integer array
    @return: Maximum profit
    """
    def maxProfit(self, prices):
        # write your code here
        maxProfit = 0
        if len(prices) == 0:
            return maxProfit
        for i in range(1, len(prices)):
            maxProfit = maxProfit + max(0, prices[i]-prices[i-1])
        return maxProfit

III

描述

假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。

样例

给出一个样例数组 [4,4,6,1,1,4,2,5], 返回 6

代码

class Solution:
    """
    @param prices: Given an integer array
    @return: Maximum profit
    """
    def maxProfit(self, prices):
        # write your code here
        if len(prices) <= 1:
            return 0
        ProfitLift = [0 for i in range(len(prices))]
        ProfitRight = [0 for i in range(len(prices))]
        minPrice = prices[0]
        for i in range(1, len(ProfitLift)):
            minPrice = min(minPrice, prices[i])
            ProfitLift[i] = max(ProfitLift[i-1], max(ProfitLift[i], prices[i]-minPrice))
        maxPrice = prices[-1]
        for i in reversed(range(1, len(ProfitRight))):
            maxPrice = max(maxPrice, prices[i])
            ProfitRight[i-1] = max(ProfitRight[i], max(ProfitRight[i-1], maxPrice-prices[i-1]))
        result = 0
        for i in range(0, len(prices)):
            result = max(result, ProfitLift[i] + ProfitRight[i])
        return result        

IV

描述

假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。
设计一个算法来找到最大的利润。你最多可以完成 k 笔交易。

样例

给定价格 = [4,4,6,1,1,4,2,5], 且 k = 2, 返回 6.

挑战

O(nk) 时间序列。

代码

class Solution:
    """
    @param nums: A list of integers
    @param k: An integer denote to find k non-overlapping subarrays
    @return: An integer denote the sum of max k non-overlapping subarrays
    """
    def maxProfit(self, K, prices):
        # write your code here
        if len(prices) <=1:
            return 0
        elif K >= len(prices):
            result = 0
            for i in range(1, len(prices)):
                result = max(prices[i]-prices[i-1], 0) + result
            return result
        else:
            Local = [[0 for i in range(K + 1)] for i in range(len(prices) + 1)]
            Global = [[0 for i in range(K + 1)] for i in range(len(prices) + 1)]
    
            for i in range(1, len(prices)+1):
                for j in range(1, K+1):
                    if j*2 > i:
                        Local[i][j] = 0
                        Global[i][j] = 0
                    else:
                        Local[i][j] = max(Local[i-1][j], Global[i-1][j-1]) + (prices[i-1] - prices[i-2])
                        Global[i][j] = max(Local[i][j], Global[i-1][j])
            return max(Global[-1])

(优化空间使用)

class Solution:
    """
    @param K: An integer
    @param prices: An integer array
    @return: Maximum profit
    """
    def maxProfit(self, K, prices):
        # write your code here
        if len(prices) <=1:
            return 0
        elif K >= len(prices):
            result = 0
            for i in range(1, len(prices)):
                result = max(prices[i]-prices[i-1], 0) + result
            return result
        else:
            Local = [[0 for j in range(K+1)] for i in range(2)]
            Global = [[0 for j in range(K+1)] for i in range(2)]
            
            for i in range(1, len(prices)+1):
                for j in range(1, K+1):
                    if j*2 >i:
                        Local[1][j] = 0
                        Global[1][j] = 0
                    else:
                        Local[1][j] = max(Local[0][j], Global[0][j-1]) + (prices[i-1] - prices[i-2])
                        Global[1][j] = max(Local[1][j], Global[0][j])
                for j in range(1, K+1):
                    Local[0][j] = Local[1][j]
                    Global[0][j] = Global[1][j]
            return max(Global[0])

题目来源

https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-i/description
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-ii/description
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii/description
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iv/description

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容