LeetCode:Best Time to Buy and Sell Stock html
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.數組
分析:題目的意思是整個過程當中只能買一隻股票而後賣出,也能夠不買股票。也就是咱們要找到一對最低價和最高價,最低價在最高價前面,以最低價買入股票,以最低價賣出股票。ide
下面三個算法時間複雜度都是O(n)spa
算法1:順序掃描股票價格,找到股票價格的第一個上升區間,以區間最低價買入,最高價賣出,後面掃描到上升區間時,根據區間的邊界更新最低價和最高價 本文地址.net
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 int len = prices.size(); 7 if(len <= 1)return 0; 8 int i = 0; 9 int ibuy = 0, isell = 0, leastBuy; 10 bool setted = false; 11 while(i < len - 1) 12 { 13 int buy, sell; 14 while(i+1 < len && prices[i+1] < prices[i])i++;//遞減區間 15 buy = i++; 16 17 while(i < len && prices[i] >= prices[i-1])i++;//遞增區間 18 sell = i-1; 19 if(setted == false) 20 { 21 ibuy = buy; 22 isell = sell; 23 leastBuy = buy; 24 setted = true; 25 } 26 else 27 { 28 if(prices[buy] <= prices[ibuy] && prices[sell] - prices[buy] >= prices[isell] - prices[ibuy]) 29 {ibuy = buy; isell = sell;} 30 if(prices[sell] > prices[isell] && prices[buy] > prices[leastBuy]) 31 {isell = sell; ibuy = leastBuy;} 32 if(prices[leastBuy] > prices[buy])leastBuy = buy; 33 } 34 } 35 return prices[isell] - prices[ibuy]; 36 } 37 };
@dslztx在評論中找出了上面算法的一個錯誤,修正以下code
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 int len = prices.size(); 7 if(len <= 1)return 0; 8 int i = 0; 9 int ibuy = 0, isell = 0, leastBuy = 0; //leastBuy爲前面已經掃描過的最低價格 10 bool setted = false; 11 while(i < len - 1) 12 { 13 int buy, sell; 14 while(i+1 < len && prices[i+1] < prices[i])i++;//遞減區間 15 buy = i++; 16 17 while(i < len && prices[i] >= prices[i-1])i++;//遞增區間 18 sell = i-1; 19 //此時從prices[buy]~prices[sell]是遞增區間 20 21 if(prices[buy] <= prices[ibuy]) 22 { 23 if(prices[sell] - prices[buy] >= prices[isell] - prices[ibuy]) 24 { 25 ibuy = buy; 26 isell = sell; 27 } 28 } 29 else 30 { 31 if(prices[sell] > prices[isell]) 32 isell = sell; 33 } 34 if(prices[buy] > prices[leastBuy]) 35 ibuy = leastBuy; 36 37 if(prices[leastBuy] > prices[buy])leastBuy = buy; 38 } 39 return prices[isell] - prices[ibuy]; 40 } 41 };
算法2:設dp[i]是[0,1,2...i]區間的最大利潤,則該問題的一維動態規劃方程以下htm
dp[i+1] = max{dp[i], prices[i+1] - minprices} ,minprices是區間[0,1,2...,i]內的最低價格blog
咱們要求解的最大利潤 = max{dp[0], dp[1], dp[2], ..., dp[n-1]} 代碼以下:遞歸
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 int len = prices.size(); 7 if(len <= 1)return 0; 8 int res = prices[1] - prices[0], minprice = prices[0]; 9 for(int i = 2; i < len; i++) 10 { 11 minprice = min(prices[i-1], minprice); 12 if(res < prices[i] - minprice) 13 res = prices[i] - minprice; 14 } 15 if(res < 0)return 0; 16 else return res; 17 } 18 };
算法3:按照股票差價構成新數組 prices[1]-prices[0], prices[2]-prices[1], prices[3]-prices[2], ..., prices[n-1]-prices[n-2]。求新數組的最大子段和就是咱們求得最大利潤,假設最大子段和是重新數組第 i 到第 j 項,那麼子段和= prices[j]-prices[j-1]+prices[j-1]-prices[j-2]+...+prices[i]-prices[i-1] = prices[j]-prices[i-1], 即prices[j]是最大價格,prices[i-1]是最小价格,且他們知足先後順序關係。代碼以下:
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 int len = prices.size(); 7 if(len <= 1)return 0; 8 int res = 0, currsum = 0; 9 for(int i = 1; i < len; i++) 10 { 11 if(currsum <= 0) 12 currsum = prices[i] - prices[i-1]; 13 else 14 currsum += prices[i] - prices[i-1]; 15 if(currsum > res) 16 res = currsum; 17 } 18 return res; 19 } 20 };
這個題能夠參考here
LeetCode: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:找到全部價格的遞增區間,每一個區間內以對低價買入最高價賣出
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 int len = prices.size(); 7 if(len <= 1)return 0; 8 int i = 0; 9 int res = 0; 10 while(i < len - 1) 11 { 12 int buy, sell; 13 //遞減區間 14 while(i+1 < len && prices[i+1] < prices[i])i++; 15 buy = i++; 16 //遞增區間 17 while(i < len && prices[i] >= prices[i-1])i++; 18 sell = i-1; 19 res += prices[sell] - prices[buy]; 20 } 21 return res; 22 } 23 };
算法2:同上一題構建股票差價數組,把數組中全部差價爲正的值加起來就是最大利潤了。其實這和算法1差很少,由於只有遞增區間內的差價是正數,而且同一遞增區間內全部差價之和 = 區間最大價格 - 區間最小价格
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 int len = prices.size(); 7 if(len <= 1)return 0; 8 int res = 0; 9 for(int i = 0; i < len-1; i++) 10 if(prices[i+1]-prices[i] > 0) 11 res += prices[i+1] - prices[i]; 12 return res; 13 } 14 };
LeetCode: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).
分析:這一題約束最多隻能買賣兩次股票,而且手上最多也只能持有一支股票。由於不能連續買入兩次股票,因此買賣兩次確定分佈在先後兩個不一樣的區間。設p(i) = 區間[0,1,2...i]的最大利潤 + 區間[i,i+1,....n-1]的最大利潤(式子中兩個區間內分別只能有一次買賣,這就是第一道題的問題),那麼本題的最大利潤 = max{p[0],p[1],p[2],...,p[n-1]}。根據第一題的算法2,咱們能夠求區間[0,1,2...i]的最大利潤;同理能夠從後往前掃描數組求區間[i,i+1,....n-1]的最大利潤,其遞歸式以下:
dp[i-1] = max{dp[i], maxprices - prices[i-1]} ,maxprices是區間[i,i+1,...,n-1]內的最高價格。 本文地址
所以兩趟掃描數組就能夠解決這個問題,代碼以下:
1 class Solution { 2 public: 3 int maxProfit(vector<int> &prices) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 const int len = prices.size(); 7 if(len <= 1)return 0; 8 int maxFromHead[len]; 9 maxFromHead[0] = 0; 10 int minprice = prices[0], maxprofit = 0; 11 for(int i = 1; i < len; i++) 12 { 13 minprice = min(prices[i-1], minprice); 14 if(maxprofit < prices[i] - minprice) 15 maxprofit = prices[i] - minprice; 16 maxFromHead[i] = maxprofit; 17 } 18 int maxprice = prices[len - 1]; 19 int res = maxFromHead[len-1]; 20 maxprofit = 0; 21 for(int i = len-2; i >=0; i--) 22 { 23 maxprice = max(maxprice, prices[i+1]); 24 if(maxprofit < maxprice - prices[i]) 25 maxprofit = maxprice - prices[i]; 26 if(res < maxFromHead[i] + maxprofit) 27 res = maxFromHead[i] + maxprofit; 28 } 29 return res; 30 } 31 };
【版權聲明】轉載請註明出處:http://www.cnblogs.com/TenosDoIt/p/3436457.html