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 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.
上題是求最大利潤,利用動態規劃的思想,在遍歷的過程中只需保留之前的最小值和最大利潤兩個值,如果當前節點減去之前的最小值的差比最大利潤大,則更新最大利潤,如果當前節點比之前的最小值小,則更新最小值,便利完成後即得到最大利潤。int maxProfit(vector<int> &prices) {
if(prices.size() <= 1)
return 0;
int min = prices[0];
int maxP = 0;
for(int i = 1; i < prices.size(); i++){
if(prices[i] - min > maxP)
maxP = prices[i] - min;
if(prices[i] < min)
min = prices[i];
}
return maxP;
}
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,2,4這三個數,交易兩次的最大利潤和交易一次的最大利潤是相同的,所以,我們在編程實現時只需將當前節點與其前一個節點進行比較,如果差值大於零,則可成交一次,同樣是遍歷一次後得到最大利潤,時間複雜度爲O(n)。int maxProfit(vector<int> &prices) {
if(prices.size() <= 1)
return 0;
int maxP = 0;
for(int i = 1; i < prices.size(); i++){
if(prices[i] > prices[i - 1])
maxP += prices[i] - prices[i - 1];
}
return maxP;
}
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).
int maxProfit(vector<int> &prices) {
if(prices.size() <= 1)
return 0;
int maxLeft = 0,maxRight = 0,max = 0;
for(int i = 2; i < prices.size(); i++){
maxLeft = maxProfit(prices,0,i);
maxRight = maxProfit(prices,i,prices.size() - 1);
if(maxLeft + maxRight > max)
max = maxLeft + maxRight;
}
return max;
}
int maxProfit(vector<int>prices,int left,int right){
if(left >= right)
return 0;
int min = prices[left];
int maxP = 0;
for(int i = left + 1; i <= right; i++){
if(prices[i] - min > maxP)
maxP = prices[i] - min;
if(prices[i] < min)
min = prices[i];
}
return maxP;
}
上述求解思路是沒問題的,接下來就是對其進行優化的問題,仍採用動態規劃的思想,此時可以借鑑騰訊2012年的校招題的做法:http://blog.csdn.net/momentforver/article/details/23266391,但不同的是,此題只需利用一個數組保存節點左邊的最大利潤,而因爲在求解節點右邊的最大利潤後即可得出最大利潤,所以沒有必要對節點右邊的最大利潤進行保存。此時空間複雜度爲O(n),需要掃描兩遍數組,所以其時間複雜度爲O(n)。
int maxProfit(vector<int> &prices) {
int len = prices.size();
if(len <= 1)
return 0;
vector<int>vLeft(len,0);
int maxP = 0,min = prices[0],max = prices[len - 1],maxProfit = 0;
for(int i = 1; i < len; i++) //求當前節點左邊的最大利潤
{
if(prices[i] - min > maxP){
maxP = prices[i] - min;
}
if(prices[i] < min)
min = prices[i];
vLeft[i] = maxP;
}
maxP = 0;
for(int i = len - 2; i >= 0; i--){ //求當前節點右邊的最大利潤,同時計算左右最大利潤
if(max - prices[i] > maxP)
maxP = max - prices[i];
if(prices[i] > max)
max = prices[i];
if(vLeft[i] + maxP > maxProfit)
maxProfit = vLeft[i] +maxP;
}
return maxProfit;
}