Leetcode | Best Time to Buy and Sell Stock
Best Time to Buy and Sell Stock I
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
这道题就是把差价最高的找出来,当然,买入点必须在卖出点之前。更新最低点,更新最低点后面的差价和总差价。
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 if (prices.size() <= 1) return 0; 5 int max = 0, min = prices[0], tmp; 6 for (int i = 0; i < prices.size(); ++i) { 7 tmp = prices[i] - min; 8 if (tmp < 0) min = prices[i]; 9 else if (tmp > max) max = tmp; 10 } 11 return max; 12 } 13 };
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 algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
方法一,需要跟踪仓位,跟踪区势,再决定买卖。
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 if (prices.size() <= 1) { 5 return 0; 6 } 7 int pos = 0, buy = 0, profit = 0, trend = -1, i = 0; 8 for (; i < prices.size() - 1; i++) { 9 if (prices[i] < prices[i + 1]) { 10 if (trend == -1 && pos == 0) { 11 buy = prices[i]; 12 pos = 1; 13 } 14 trend = 1; 15 } else if (prices[i] > prices[i + 1]) { 16 if (trend == 1 && pos > 0) { 17 profit += (prices[i] - buy); 18 pos = 0; 19 } 20 trend = -1; 21 } 22 } 23 if (pos > 0) { 24 profit += (prices[i] - buy); 25 } 26 return profit; 27 } 28 };
方法二,上面的方法太复杂了。因为允许无限次的操作,所以只要是正的操作就都可以,把它们加起来就是了。
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 if (prices.size() <= 1) { 5 return 0; 6 } 7 int profit = 0, diff = 0; 8 for (int i = 0; i < prices.size() - 1; i++) { 9 diff = prices[i + 1] - prices[i]; 10 if (diff > 0) profit += diff; 11 } 12 return profit; 13 } 14 };
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.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
一开始以为像第二题那么做就可以了,求每个波段的profit,然后将最大两个相加。Wrong Answer。想想也是,比如1,2,4,2,5,7,按这种算法得到的最大值是7-2=5,实际上应该是7-1=6。
于是改用DP的算法,设p[i...j]为从第i天到第j天的一次操作最大收益,我们要求的其实是p[0...n-1]。
最后的结果其实是max{p[0...k]+p[k+1...n-1], p[0...n-1]}。
这里其实已经包含以下两种情况:
1. [0, m]进行两次操作,[m+1,n-1]不进行操作。对应地可以找到0<k<m,使得在[0,k]进行一次操作,[k+1,m]进行另一次操作。[m+1,n-1]不进行操作,因为在[k+1,m]里已经找到[k+1,n-1]的最大获益区间。
2. [0,m]不进行操作,[m+1,n-1]进行两次操作。同1.
p[0..k]就是第一题啦,p[k+1...n-1]思路同p[0...k],就是反向操作,只是p[0...k]是更新最低点,p[k+1...n-1]是更新最高点。
代码如下:
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 if (prices.size() <= 1) return 0; 5 6 int n = prices.size(); 7 vector<int> max(n, 0); 8 9 // max[0...i] 10 int min = prices[0], t, m = 0; 11 for (int i = 1; i < prices.size(); ++i) { 12 t = prices[i] - min; 13 if (t < 0) min = prices[i]; 14 else if (t > m) m = t; 15 max[i] = m; 16 17 } 18 19 int ret = max[n - 1], p = 0; 20 m = prices[n - 1]; 21 // max[j...n-1] 22 for (int j = n - 2; j >= 1; --j) { 23 t = m - prices[j]; 24 if (t < 0) m = prices[j]; 25 else if (t > p) { 26 p = t; 27 if (p + max[j - 1] > ret) ret = p + max[j - 1]; 28 } 29 } 30 return ret; 31 } 32 };