[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 ...
随机推荐
- jquery选择器之全选择器
在CSS中,经常会在第一行写下这样一段样式 * {padding: 0; margin: 0;} 通配符*意味着给所有的元素设置默认的边距.jQuery中我们也可以通过传递*选择器来选中文档页面中的元 ...
- mysql类似to_char()to_date()函数mysql日期和字符相互转换方法date_f
mysql 类似to_char() to_date()函数mysql日期和字符相互转换方法 date_format(date,'%Y-%m-%d') -------------->oracle中 ...
- C#启动计算器并设计算器为活动窗口
启动计算器,并获取焦点 using System; using System.Runtime.InteropServices; namespace ConsoleApplication3 { clas ...
- pytho模块的加载顺序
当前目录如果有同名的系统模块,那么当前目录的模块会被import,系统模块会被忽略,如: 1 ghostwu@ghostwu:~/python/module$ ls 2 import_test.py ...
- shell部分面试题
1.用Shell编程,判断一文件是不是块或字符设备文件,如果是将其拷贝到 /dev 目录下. #!/bin/bash#1.sh#判断一文件是不是字符或块设备文件,如果是将其拷贝到 /dev 目录下#f ...
- 让更多浏览器支持html5元素的简单方法
当我们试图使用web上的新技术的时候,旧式浏览器总是我们心中不可磨灭的痛!事实上,所有浏览器都有或多或少的问题,现在还没有浏览器能够完整的识别和支持最新的html5结构元素.但是不用担心,你依然可以在 ...
- 前端知识--控制input按钮的可用和不可用
最近在项目的开发的时候,自己虽然是写后端的,但是,在开发核心的时候,前端的知识自己还是会用到的,多以前端这块自己由于好长时间都没有去看,所以几乎已经忘记的差不多了,现在也只能是想起一点记录一点,以便能 ...
- Cocos2d-x学习小结 配置篇
Cocos2d-x学习小结 配置篇 学习工具:Cocos2d-x用户手册,<Cocos2d-x游戏开发之旅> 首先官网下载cocos2d-x源码,安装vs2019.如果没有安装python ...
- fastjson<=1.2.47反序列化RCE漏洞
介绍:fastjson是一个Java语言编写的高性能功能完善的JSON库. 漏洞原因:fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并通过json来填充其属性 ...
- S1_搭建分布式OpenStack集群_08 网络服务(neutron)安装部署
一.数据库配置(控制节点)创建数据库以及用户:# mysql -uroot -p12345678MariaDB [(none)]> CREATE DATABASE neutron;MariaDB ...