[LeetCode] 123. Best Time to Buy and Sell Stock III 买卖股票的最佳时间 III
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 (i.e., you must sell the stock before you buy again).
Example 1:
Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
Example 2:
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
给定一个元素代表某股票每天价格的数组,最多可以买卖股票2次,还是不能同时有多个交易,买之前要卖出,求最大利润。
两次买卖在时间跨度上不能有重叠(当然第一次的卖出时间和第二次的买入时间可以是同一天)。既然不能有重叠可以将整个序列以任意坐标i为分割点,分割成两部分:
prices[0:n-1] => prices[0:i] + prices[i:n-1],对于这个分割来说,最大收益为两段的最大收益之和。每一段的最大收益用I的解法来做。最大收益是对所有0<=i<=n-1的分割的最大收益取一个最大值。
1. 计算A[0:i]的收益最大值:用minPrice记录i左边的最低价格,用maxLeftProfit记录左侧最大收益
2. 计算A[i:n-1]的收益最大值:用maxPrices记录i右边的最高价格,用maxRightProfit记录右侧最大收益。
3. 最后这两个收益之和便是以i为分割的最大收益。将序列从左向右扫一遍可以获取dp1,从右向左扫一遍可以获取dp2。相加后取最大值即为答案。
时间复杂度O(n), 空间复杂度O(n)
Java:Divide and conquer
public class Solution {
public int maxProfit(int[] prices) {
// find maxProfit for {0, j}, find maxProfit for {j + 1, n - 1}
// find max for {max{0, j}, max{j + 1, n - 1}}
if (prices == null || prices.length == 0) {
return 0;
}
int maximumProfit = 0;
int n = prices.length;
ArrayList<Profit> preMaxProfit = new ArrayList<Profit>(n);
ArrayList<Profit> postMaxProfit = new ArrayList<Profit>(n);
for (int i = 0; i < n; i++) {
preMaxProfit.add(maxProfitHelper(prices, 0, i));
postMaxProfit.add(maxProfitHelper(prices, i + 1, n - 1));
}
for (int i = 0; i < n; i++) {
int profit = preMaxProfit.get(i).maxProfit + postMaxProfit.get(i).maxProfit;
maximumProfit = Math.max(profit, maximumProfit);
}
return maximumProfit;
}
private Profit maxProfitHelper(int[] prices, int startIndex, int endIndex) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
for (int i = startIndex; i <= endIndex; i++) {
if (prices[i] < minPrice) {
minPrice = prices[i];
}
if (prices[i] - minPrice > maxProfit) {
maxProfit = prices[i] - minPrice;
}
}
return new Profit(maxProfit, minPrice);
}
public static void main(String[] args) {
int[] prices = new int[]{4,4,6,1,1,4,2,5};
Solution s = new Solution();
System.out.println(s.maxProfit(prices));
}
};
class Profit {
int maxProfit, minPrice;
Profit(int maxProfit, int minPrice) {
this.maxProfit = maxProfit;
this.minPrice = minPrice;
}
}
Java:DP
public class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1) {
return 0;
}
int[] left = new int[prices.length];
int[] right = new int[prices.length];
// DP from left to right;
left[0] = 0;
int min = prices[0];
for (int i = 1; i < prices.length; i++) {
min = Math.min(prices[i], min);
left[i] = Math.max(left[i - 1], prices[i] - min);
}
//DP from right to left;
right[prices.length - 1] = 0;
int max = prices[prices.length - 1];
for (int i = prices.length - 2; i >= 0; i--) {
max = Math.max(prices[i], max);
right[i] = Math.max(right[i + 1], max - prices[i]);
}
int profit = 0;
for (int i = 0; i < prices.length; i++){
profit = Math.max(left[i] + right[i], profit);
}
return profit;
}
}
Python:T:O(n), S: O(n)
class Solution3:
def maxProfit(self, prices):
min_price, max_profit_from_left, max_profits_from_left = float("inf"), 0, []
for price in prices:
min_price = min(min_price, price)
max_profit_from_left = max(max_profit_from_left, price - min_price)
max_profits_from_left.append(max_profit_from_left) max_price, max_profit_from_right, max_profits_from_right = 0, 0, []
for i in reversed(range(len(prices))):
max_price = max(max_price, prices[i])
max_profit_from_right = max(max_profit_from_right, max_price - prices[i])
max_profits_from_right.insert(0, max_profit_from_right) max_profit = 0
for i in range(len(prices)):
max_profit = max(max_profit, max_profits_from_left[i] + max_profits_from_right[i]) return max_profit
Python:
class Solution:
def maxProfit(self, prices):
hold1, hold2 = float("-inf"), float("-inf")
release1, release2 = 0, 0
for i in prices:
release2 = max(release2, hold2 + i)
hold2 = max(hold2, release1 - i)
release1 = max(release1, hold1 + i)
hold1 = max(hold1, -i);
return release2
C++:DP
class Solution {
public:
int maxProfit(vector<int> &prices) {
if(prices.empty()) return 0;
int n = prices.size();
vector<int> leftProfit(n,0);
int maxLeftProfit = 0, minPrice = prices[0];
for(int i=1; i<n; i++) {
if(prices[i]<minPrice)
minPrice = prices[i];
else
maxLeftProfit = max(maxLeftProfit, prices[i]-minPrice);
leftProfit[i] = maxLeftProfit;
}
int ret = leftProfit[n-1];
int maxRightProfit = 0, maxPrice = prices[n-1];
for(int i=n-2; i>=0; i--) {
if(prices[i]>maxPrice)
maxPrice = prices[i];
else
maxRightProfit = max(maxRightProfit, maxPrice-prices[i]);
ret = max(ret, maxRightProfit + leftProfit[i]);
}
return ret;
}
};
类似题目:
[LeetCode] 121. Best Time to Buy and Sell Stock 买卖股票的最佳时间
[LeetCode] 122. Best Time to Buy and Sell Stock II 买卖股票的最佳时间 II
[LeetCode] 188. Best Time to Buy and Sell Stock IV 买卖股票的最佳时间 IV
[LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期
All LeetCode Questions List 题目汇总
[LeetCode] 123. Best Time to Buy and Sell Stock III 买卖股票的最佳时间 III的更多相关文章
- [LeetCode] 122. 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 ...
- [LeetCode] 188. Best Time to Buy and Sell Stock IV 买卖股票的最佳时间 IV
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- [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 ...
- LeetCode 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 ...
- [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 ...
- LN : leetcode 123 Best Time to Buy and Sell Stock III
lc 123 Best Time to Buy and Sell Stock III 123 Best Time to Buy and Sell Stock III Say you have an a ...
- [leetcode]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 ...
- 122 Best Time to Buy and Sell Stock II 买卖股票的最佳时机 II
假设有一个数组,它的第 i 个元素是一个给定的股票在第 i 天的价格.设计一个算法来找到最大的利润.你可以完成尽可能多的交易(多次买卖股票).然而,你不能同时参与多个交易(你必须在再次购买前出售股票) ...
- Java for LeetCode 123 Best Time to Buy and Sell Stock III【HARD】
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
随机推荐
- python的pandas库读取csv
首先建立test.csv原始数据,内容如下 时间,地点 一月,北京 二月,上海 三月,广东 四月,深圳 五月,河南 六月,郑州 七月,新密 八月,大连 九月,盘锦 十月,沈阳 十一月,武汉 十二月,南 ...
- Java 出现cannot be resolved to a type
package com.sysutil.util; /* thishi duo zhu */ // dan zhshi import com.sysutil.util.*; class Example ...
- DT6.0框架留言模块漏洞修复
今天早上登入后台,留言被国外乱码注入一大堆,很烦人,得去数据库清空.所以仔细检查dt的留言模块,找到解决办法. 在:module/extend/guestbook.inc.php 大约第10行左右 i ...
- 用Queue控制python多线程并发数量
python多线程如果不进行并发数量控制,在启动线程数量多到一定程度后,会造成线程无法启动的错误. 下面介绍用Queue控制多线程并发数量的方法(python3). # -*- coding: utf ...
- JavaScript——判断页面是否加载完成
前言 接上文,既然你是做一个loading的效果,你总不能一直loading,当页面完成加载的时候你总要结束吧 步骤 先说下原生的方法,再讲jquery的方法,原理是一样的 JavaScript // ...
- Spring Security 认证执行流程
本文基于 Spring Security 5.x 推荐阅读: 项目集成Spring Security SpringSecurity 整合 JWT 一.外层-正常登陆调用 项目启动后会自动寻找 User ...
- 第三章 - SQL基础及元数据获取
SQL的介绍 SQL的定义:结构化查询语句 SQL的作用:对库和表进行操作 SQL的常用分类 DDL 数据定义语言(Data Definition Language) DCL 数据控制语言(Data ...
- 【JZOJ6217】【20190614】最大面积
题意 平面上有\(n\)个点\(A_i\),\(q\)次询问,每次给出一个点\(P\),求: \[ \sum_{i=L}^{R} 2S_{\triangle OPA_i} \] 最大值,其中$S_{\ ...
- BZOJ1034 ZJOJ2008 泡泡堂BNB
BZOJ1034 ZJOJ2008 泡泡堂BNB Description 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省的代表 队由n名选手组成,比赛 ...
- js constructor typeOf 区别
constructor 属性返回对创建此对象的数组函数的引用. 例如:const obj = {a: 1} console.log(obj.constructor) // funct ...