[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 ...
随机推荐
- LeetCode初级算法--其他02:有效的括号
LeetCode初级算法--其他02:有效的括号 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- P1525 关押罪犯[扩展域并查集]
题目来源:洛谷 题目描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1−N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整 ...
- django 项目需要注意的一些点
1.创建新项目 把静态文件夹的名字放在settings文件里面 STATIC_URL = '/static/' STATICFILES_DIRS=[ os.path.join(BASE_DIR, ...
- python完成数组格式的请求参数的加密计算
#输入 '''order_id:31489 join_course[0][join_tel]:13130999882 join_course[0][join_name]:任学雨 join_course ...
- python变量选中后高亮显示
file>settings>editor>color scheme>general>code>identifier under caret>backgroun ...
- 线性回归和Ridge回归
网址:https://www.cnblogs.com/pinard/p/6023000.html 线性回归和交叉验证 import matplotlib.pyplot as plt import nu ...
- LeetCode 1105. Filling Bookcase Shelves
原题链接在这里:https://leetcode.com/problems/filling-bookcase-shelves/ 题目: We have a sequence of books: the ...
- 查看.NET应用程序中的异常(下)
为什么要使用内存转储进行调试? 在两种主要情况下,您可能需要使用内存转储进行调试.第一种情况是应用程序有一个未处理的异常并崩溃,而您只有一个内存转储.第二种情况是,在生产环境中出现异常或特定行为,并且 ...
- 用Xpath选择器解析网页(lxml)
在<爬虫基础以及一个简单的实例>一文中,我们使用了正则表达式来解析爬取的网页.但是正则表达式有些繁琐,使用起来不是那么方便.这次我们试一下用Xpath选择器来解析网页. 首先,什么是XPa ...
- 错误: 找不到或无法加载主类 Welcome.java
问题原因: 不需要带.java