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. Web安全之SQL注入攻击技巧与防范

    http://www.plhwin.com/2014/06/13/web-security-sql/

  2. Pivot Table

    1. Disable menu 'Disable show/hide Field list menu sht.PivotTables().EnableFieldList = False ''scrip ...

  3. java的锁机制

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在Java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...

  4. js传入参数为字符串问题

    示例: var device_mac="11qweq234ert"; //第一种方式会报错:Onclick SyntaxError: identifier starts immed ...

  5. redis的一些操作

    public class WnsRedisFactory { private static Cache pool = null; private static JedisConnectionFacto ...

  6. Lisp永远成不了编程主流语言

        Lisp语言是第二古老的高级编程语言.许多的黑客和开发者对Lisp推崇备至,Paul Graham甚至说"编程语言现在的发展,不过刚刚赶上1958年Lisp语言的水平". ...

  7. zepto之tap事件点透问题分析及解决方案

    点透现象出现的场景: 当A/B两个层上下z轴重叠,上层的A点击后消失或移开(这一点很重要),并且B元素本身有默认click事件(如a标签)或绑定了click事件.在这种情况下,点击A/B重叠的部分,就 ...

  8. How to use Bundle&Minifier and bundleconfig.json in ASP.NET Core

    引言 我们在ASP.NET MVC 中经常会用到 bundleConfig.cs 文件来进行我们 css 和 js 的绑定, 那么在ASP.NET Core 中我们应该如何使用呢? 步骤一 在 Vis ...

  9. 【Python图像】给你的头像+1

    早些年,微信朋友圈有段时间非常流行这个头像+1的套路,简直逼死强迫症. 将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 涉及知识: Pyt ...

  10. 【Python网络爬虫二】使用urllib2抓去网页内容

    在Python中通过导入urllib2组件,来完成网页的抓取工作.在python3.x中被改为urllib.request. 爬取具体的过程类似于使用程序模拟IE浏览器的功能,把URL作为HTTP请求 ...