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