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

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

当遇到限制次数以及求最大的要求时,很自然要联想到动规。

动规中不同的状态设计,会有不同的时间复杂度。

本题有两种解法:

(1)

我最开始想到的是下面这种解法,但是Memory Limit Exceeced.

O(n^2)的解法

很自然的我们会想到记录从开头到第i个字符中进行k次交易能够得到的最大收益,记为dp[i][k].

进行更新:dp[i][k] = max{dp[j][k-1]+maxprofit(j...i)}, 0 <= j < i

这里我们需要用到每个可能的区间中进行一次交易的最大收益,也就是I中的问题。

预先计算出所有的maxprofit的复杂度是O(n^2),dp的复杂度也是O(n^2).

Code:

class Solution {
public:
int maxProfit(vector<int> &prices) {
int n = prices.size();
if(n == 0) return 0;
vector<vector<int>> dp(n, vector<int>(3,0));
vector<vector<int>> maxprofit(n, vector<int>(n, 0)); for(int i = 0; i < n; i++)
{
int curmin = prices[i];
int curprofit = 0;
for(int j = i+1; j < n; j++)
{
if(prices[j] < curmin) curmin = prices[j];
else{
int gap = prices[j] - curmin;
if(gap > curprofit) curprofit = gap;
}
maxprofit[i][j] = curprofit;
if(i == 0) dp[j][1] = curprofit;
}
} for(int i = 1; i < n; i++)
{
int tmp = dp[0][1] + maxprofit[0][i];
for(int j = 1; j < i; j++)
{
if(dp[j][1] + maxprofit[j][i] > tmp) tmp = dp[j][1]+maxprofit[j][i];
}
dp[i][2] = tmp;
} return dp[n-1][2];
}
};

(2)O(n)的解法

参考了这个:http://blog.csdn.net/linhuanmars/article/details/23236995

从上面的分析中我们很容易找出一个case, 例如有一个区间差异特别大,在很长时间内都是最优的选择,而我们的dp却需要不断的枚举一些不可能构成最终解的区间。

怎么样更聪明的定义状态呢?

上一种定义中,我们是定义(i,j)中的最大的解,这样不同的(i,j)对对应的可能是同一种解;这样我们可以用一个global变量来存储;但是由于处理的区间是不断延伸的,后面出现的数字可能和当前末尾的组合起来行程更大的区间,因此我们用一个local变量存储当前以i结尾的最大的解的值。

扩展到能够选择k个区间,我们定义:

global(i,k) 表示截止到第i天,进行k次交易能够获得的最优解(不一定以最后一天结束)

local(i,k) 表示以第i天结束的k次交易能够获得的最优解

能够得到递推式:

local[i][k] = max{global[i-1][k-1], local[i-1][k]} + prices[i] - prices[i-1];

global[i][k] = max{global[i-1][k], local[i][k]};

初始值全为零,最终解为global[n-1][2]。

Code:

class Solution {
public:
int maxProfit(vector<int> &prices) {
int n = prices.size();
if(n == 0) return 0;
vector<vector<int>> global(n, vector<int>(3,0));
vector<vector<int>> local(n, vector<int>(3,0)); for(int j = 1; j <= 2; j++)
{
for(int i = 1; i < n; i++)
{
local[i][j] = max(global[i-1][j-1], local[i-1][j]) + prices[i] - prices[i-1];
global[i][j] = max(global[i-1][j], local[i][j]);
}
}
return global[n-1][2];
}
};

 

从其他博客中找到了一种O(n)的解法,思路更简单,但是不具备从2次交易推广到k次的潜力。

主要的思路就是从前往后扫描一遍,找到从0到i的一次交易的最大收益,然后从后往前扫描一遍,得到从i+1到n-1的最大收益。然后两者相加取最大即可。

传送门:http://fisherlei.blogspot.com/2013/01/leetcode-best-time-to-buy-and-sell_3958.html

4 Best Time to Buy and Sell Stock III_Leetcode的更多相关文章

  1. [LeetCode] Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期

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

  2. [LeetCode] Best Time to Buy and Sell Stock IV 买卖股票的最佳时间之四

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

  3. [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 ...

  4. [LeetCode] 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 ...

  5. [LeetCode] 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 ...

  6. [LintCode] 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 ...

  7. [LintCode] 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 ...

  8. LeetCode——Best Time to Buy and Sell Stock II (股票买卖时机问题2)

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

  9. 123. Best Time to Buy and Sell Stock (三) leetcode解题笔记

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

随机推荐

  1. SpringMVC学习记录3

    这次的主题 最近一直在学习SpringMVC..(这句话我已经至少写了3,4遍了....).这次的研究主要是RequestMappingHandlerAdapter中的各种ArgumentsResol ...

  2. Git on Windows 一些问题

    问题汇总 1. 卸载Git时,bin和usr目录删不掉 报错:bin, usr目前需要admin权限删除,或者这个目录被其他文件引用 打开taskmgr,找到所有引用 git/bin/ 下的文件的进程 ...

  3. 04 MapReduce原理介绍

    大数据实战(上) # MapReduce原理介绍 大纲: * Mapreduce介绍 * MapReduce2运行原理 * shuffle及排序    定义 * Mapreduce 最早是由googl ...

  4. IP分片详解

    IP分片是网络上传输IP报文的一种技术手段.IP协议在传输数据包时,将数据报文分为若干分片进行传输,并在目标系统中进行重组.不同的链路类型规定有不同最大长度的链路层数据帧,称为链路层MTU(最大传输单 ...

  5. Python绘图

    1.二维绘图 a. 一维数据集 用 Numpy ndarray 作为数据传入 ply 1. import numpy as np import matplotlib as mpl import mat ...

  6. 使用php+swoole对client数据实时更新(下)

    上一篇提到了swoole的基本使用,现在通过几行基本的语句来实现比较复杂的逻辑操作: 先说一下业务场景.我们目前的大多数应用都是以服务端+接口+客户端的方式去协调工作的,这样的好处在于不论是处在何种终 ...

  7. webpack那些事儿

    webpack那些事儿01-webpack到底是什么 webpack那些事儿02-从零开始 webpack那些事儿03-热插拔 hot webpack那些事儿04-spa项目实战分析 webpack那 ...

  8. Vim 资料总结

    vi/vim基本使用方法:http://www.cnblogs.com/itech/archive/2009/04/17/1438439.html Vim命令合集: http://www.cnblog ...

  9. 理解 Delphi 的类(八) - 关于类的定义

      //标准语法   TMyClass1 = class(TObject)   end;   //如果是继承自 TObject 可以省略   TMyClass2 = class   end;   // ...

  10. Docker - Install docker on CentOS

    1. 准备 由于 Dokcer 需要 64bit OS, 版本号 3.10 或者更新的版本.所以,需要我们先确认我们的 CentOS 系统 $ uname -r output :: 3.10.0-22 ...