from : https://leetcode.com/problems/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 algorithm to find the maximum profit. You may complete at most two transactions.
class Solution {
public:
int maxProfit(vector<int>& prices) {
int days = prices.size();
if(days <= 1) {
return 0;
}
int *left = new int[days]; // left[i]:inlcude ith day, can make most.
int *right = new int[days];
// for left
int v = prices[0];
left[0] = 0;
for(int i=1; i<days; ++i) {
if(v > prices[i]) {
v = prices[i];
}
left[i] = max(left[i-1], prices[i] - v);
}
// for right
v = prices[days-1];
right[days-1] = 0;
for(int i=days-2; i>=0; --i) {
if(v < prices[i]) {
v = prices[i];
}
right[i] = max(right[i+1], v - prices[i]);
}
int made = 0;
for(int i=0; i<days; ++i) {
if(made < left[i] + right[i]) {
made = left[i] + right[i];
}
}
delete[] left;
delete[] right;
return made;
}
};
public class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length < 2) {
return 0;
}
int n = prices.length;
int[] t1 = new int[n];// t1[i]:在i和i之前卖,最大获利
int[] t2 = new int[n];// t2[i]:在i和i之后买,最大获利
int a = prices[0];
int p = 0;
for(int i=1; i<n; ++i) {
if(prices[i] < a) {
a = prices[i];
}
if(prices[i] -a >p) {
p = prices[i]-a;
}
t1[i] = p;
}
a = prices[n-1];
p = 0;
for(int i=n-2; i>=0; --i) {
if(prices[i] > a) {
a = prices[i];
}
if(a - prices[i] > p) {
p = a-prices[i];
}
t2[i] = p;
}
p = 0;
for(int i=0; i<n; ++i) {
if(t1[i]+t2[i] > p) {
p = t1[i]+t2[i];
}
}
return p;
}
}
最近被问如何求出买入和卖出点的问题,于是用java写了下面的代码。
package dp;
import java.util.ArrayList;
import java.util.List;
public class StockBaidu {
class Choice {
int buyAt;
int selAt;
public Choice(int buy, int sel) {
buyAt = buy;
selAt = sel;
}
}
class Profit {
Choice chioce;
int sum;
public Profit(Choice c, int s) {
chioce = c;
sum = s;
}
}
public List<Choice> maxProfit(int[] prices) {
List<Choice> ans = new ArrayList<Choice>();
int days = prices.length;
if (days <= 1) {
return ans;
}
Profit[] left = new Profit[days]; // left[i]:inlcude ith day, can make most.
Profit[] right = new Profit[days];
// for left
int k = 0;
int v = prices[0];
left[0] = new Profit(new Choice(0, 0), 0);
for (int i = 1; i < days; ++i) {
if (v > prices[i]) {
v = prices[i];
k = i;
}
left[i] = choose(left[i-1], prices[i]-v, k, i);
}
// for right
k = days - 1;
v = prices[k];
right[days - 1] = new Profit(new Choice(days - 1, days - 1), 0);
for (int i = days - 2; i >= 0; --i) {
if (v < prices[i]) {
v = prices[i];
k = i;
}
right[i] = choose(right[i+1], v-prices[i], i, k);
}
int made = 0;
for (int i = 0; i < days; ++i) {
if (made < left[i].sum + right[i].sum) {
ans.clear();
if(left[i].chioce.buyAt < left[i].chioce.selAt) {
ans.add(left[i].chioce);
}
if(right[i].chioce.buyAt < right[i].chioce.selAt) {
ans.add(right[i].chioce);
}
made = left[i].sum + right[i].sum;
}
}
return ans;
}
public int maximumProfit(int[] prices) {
int days = prices.length;
if(days <= 1) {
return 0;
}
int[] left = new int[days];
int[] right = new int[days];
// for left
int v = prices[0];
left[0] = 0;
for(int i=1; i<days; ++i) {
if(v > prices[i]) {
v = prices[i];
}
left[i] = Math.max(left[i-1], prices[i] - v);
}
// for right
v = prices[days-1];
right[days-1] = 0;
for(int i=days-2; i>=0; --i) {
if(v < prices[i]) {
v = prices[i];
}
right[i] = Math.max(right[i+1], v - prices[i]);
}
int made = 0;
for(int i=0; i<days; ++i) {
if(made < left[i] + right[i]) {
made = left[i] + right[i];
}
}
return made;
}
private Profit choose(Profit before, int profit, int buyAt, int selAt) {
if(before.sum >= profit) {
return before;
}
return new Profit(new Choice(buyAt, selAt), profit);
}
public static void main(String[] args) {
int[] data = {4,1,9,3,6,5,2,1,4,9,3,4,2,5,9};
int profit = 0;
for(Choice c : new StockBaidu().maxProfit(data)) {
profit += data[c.selAt] - data[c.buyAt];
System.out.println("profit is " + profit);
System.out.println("buy at " + c.buyAt + ": sell at " + c.selAt);
}
System.out.println(new StockBaidu().maximumProfit(data));
int[] data2 = {9, 2, 6};
int profit2 = 0;
for(Choice c : new StockBaidu().maxProfit(data2)) {
profit2 += data2[c.selAt] - data2[c.buyAt];
System.out.println("profit is " + profit2);
System.out.println("buy at " + c.buyAt + ": sell at " + c.selAt);
}
System.out.println(new StockBaidu().maximumProfit(data2));
}
}