Problem Link:

http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/


Linear Time Solution

We try to solve this problem in O(n) time in the help of the algorithm in Best Time to Buy and Sell Stock, which can return the max profit by given a list of prices.

As transaction definition in Best Time to Buy and Sell Stock, we modify the algorithm that returns the best transaction (b, s) by given price list prices[0:n] where

  1. prices[i] <= prices[s0], for i = b0, ..., n-1
  2. prices[i] >= prices[b0], for i = 0, ..., s0

By the help of method find_best_transaction, the following algorithm will solve the problem in O(n) time:

1. By given the price list prices[0..n01], find the best transaction (b,s) = find_best_transaction(prices)
2. Find the maximum profit for the following three parts divided by b and s:
P1: the maximum profit for the price list price[0..b-1]
P2: the maximum profit for the price list price[b+1..s-1].inverse()
P3: the maximum profit for the price list price[s+1..n-1]
3. Return prices[s]-prices[b] + max(P1,P2,P3)
 

Correctness

Now we woul prove the algorithm above is correct. Sicne we are asked to find at most two transactions, there are two cases: 1) (b0, s0) is one of the two transactions; 2) (b0, s0) is not in the result. For case 1) we can solve the problem by find the max profit for prices[0:b0] and prices[s0:n], and choose the bigger one as the second transaction.

Now we consider the case 2), let (b1, s1) and (b2, s2) be the two transactions where 0 <= b1 < s1 < b2 < s2 <= n-1. Also, we can have the following corolarries:

  1. b0 <= s1 <= s0, we prove it by contradiction:
    1. if s1 < b0 (-----s1--b0-----s0------), then (b2,s2) could be replaced by (b0, s0).
    2. if s1 > s0 (----b0----s0--s1--------), then (b1, s1) could be replaced by (b0, s0).
  2. b0 <= b2 <= s0, we prove it by contradiction:
    1. if b2 < b0 (---b2----b0-------s0---), then (b2, s2) could be replaced by (b0, s0).
    2. if b2 > s0 (---------b0----s0--b2--), then (b1, s1) could be replaced by (b0, s0).
  3. For b1 < s1, since s1 <= s0, then s1 could be b0, since prices[b0] <= prices[i] for i = 0,...,s0.
  4. For s2 > b2, since b2 >= b0, then s2 could be s0, since prices[s0] <= prices[i] for i = b0, ..., n-1

Therefore, we can find the best s1 and b2 scanning between b1(b0) and s2(s0), which only takes O(n) time and is a little tricky.

Suppose the optimal trasactions can be as follows:

    -----b1(b0)----s1------b2------s2(s0)----

The profit should be (p[s1] - p[b1]) + (p[s2]-p[b2]) which can be rewritten as (p[s2]-p[b1]) + (p[s1]-p[b2]). Therefore, it equals to finding best transaction (b2, s1) where the given prices list is the inverse of prices[b1+1, ..., s2-1].

From the two cases above, our algorithm will give the correct answer.


Python Code

The following is the python implementation accepted by oj.leetcode.com.

class Solution:
# @param prices, a list of integer
# @return an integer
def maxProfit(self, prices):
n = len(prices)
if n < 2:
return 0
# Find the single best transaction
b0, s0, profit0 = self.find_best_transaction(prices) # Calculate the max profit of the three parts partitioned by (b0, s0)
profit1 = profit2 = profit3 = 0
if b0 > 0:
profit1 = self.find_best_transaction(prices[:b0])[2]
if s0 > b0 + 1:
profit2 = self.find_best_transaction(prices[b0+1:s0][::-1])[2]
if s0 < n-1:
profit3 = self.find_best_transaction(prices[s0+1:])[2] # Return the best case
return profit0 + max(profit1, profit2, profit3) def find_best_transaction(self, prices):
"""
Return the transaction (b,s) that obtains maximum profit.
@param prices: a list of prices
@return: (b,s) where 0 <= b < s < len(prices)
"""
# Initialize with prices[0]
b = s = l = 0
# Scan from i = 1 to n-1
for i in xrange(1, len(prices)):
if prices[i] <= prices[l]:
l = i
elif prices[i] > prices[s] or prices[s] - prices[b] < prices[i] - prices[l]:
s = i
b = l
return b, s, prices[s]-prices[b]

【LeetCode OJ】Best Time to Buy and Sell Stock III的更多相关文章

  1. 【LeetCode OJ】Best Time to Buy and Sell Stock II

    Problem Link: http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ We solve this prob ...

  2. 【LeetCode OJ】Best Time to Buy and Sell Stock

    Problem Link: http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock/ We solve this problem ...

  3. LeetCode OJ 123. Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  4. 【leetcode】Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  5. LeetCode 笔记23 Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  6. 【leetcode刷题笔记】Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  7. LeetCode OJ 122. Best Time to Buy and Sell Stock II

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  8. LeetCode OJ 121. 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 ...

  9. LeetCode OJ:Best Time to Buy and Sell Stock II(股票买入卖出最佳实际II)

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

随机推荐

  1. Qt之QThread(深入理解)

    简述 为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程.对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题. 前面,已 ...

  2. listview加载性能优化ViewHolder

    在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局, 但当listview有大量的数据需要加载的时候 ...

  3. mouseover 和 hover 方法

    mouseover 和 hover 方法的不同?jquery   hover包括了鼠标移到对象上,同时鼠标再移出对象的过程,相应的子类也被选中. mouseover是鼠标经过对象时,不包含他的子类同时 ...

  4. struts2视频学习笔记 15-17 (访问或添加request属性,文件上传)

    课时15 访问或添加request/session/application属性 1.简单说 page指当前页面.在一个jsp页面里有效 2.request 指从http请求到服务器处理结束,返回响应的 ...

  5. PDF 补丁丁 0.4.1.804 测试版发布:合并文件夹的图片和PDF文件,自由生成多层次书签

    新的测试版增强了合并文件的功能,可以合并文件夹内的图片和PDF文件,还可以在合并文件列表上直接指定与合并文件对应的PDF书签标题.通过拖放文件项目生成多层次的PDF书签.如下图所示: 另外,新的测试版 ...

  6. bzoj 2730: [HNOI2012]矿场搭建

    #include<cstdio> #include<cstring> #include<iostream> #define M 508 using namespac ...

  7. android selector详解

    --> 改变字体的颜色<selector xmlns:android="http://schemas.android.com/apk/res/android"> ...

  8. SQL Server 语句整理

    1. 创建数据库 create database dbName 2. 删除数据库 drop database dbName 3. 备份sql server --- 创建 备份数据的 device US ...

  9. iOS多语言备选机制

    近期伊书突然接到一些外国用户的投诉,说伊书界面变成了中文,但他们系统语言不是中文,是法文俄文日文等,伊书只支持中文跟英文,在不支持系统所用语言的时候,理应会自动选用英文,不知为什么会选成了中文,经过艰 ...

  10. Android模拟器配置选项说明

    Memory Options是模拟器的运行内存大小,类比电脑内存大小,就是在设置->应用程序中,正在运行标签页下面显示的那个大小Internal storage是模拟器内置存储空间大小,用于存放 ...