LeetCode:Best Time to Buy and Sell Stock I II III
LeetCode: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.
分析:题目的意思是整个过程中只能买一只股票然后卖出,也可以不买股票。也就是我们要找到一对最低价和最高价,最低价在最高价前面,以最低价买入股票,以最低价卖出股票。
下面三个算法时间复杂度都是O(n)
算法1:顺序扫描股票价格,找到股票价格的第一个上升区间,以区间最低价买入,最高价卖出,后面扫描到上升区间时,根据区间的边界更新最低价和最高价 本文地址
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         int len = prices.size();
         if(len <= )return ;
         int i = ;
         int ibuy = , isell = , leastBuy;
         bool setted = false;
         while(i < len - )
         {
             int buy, sell;
             while(i+ < len && prices[i+] < prices[i])i++;//递减区间
             buy = i++;
             while(i < len && prices[i] >= prices[i-])i++;//递增区间
             sell = i-;
             if(setted == false)
             {
                 ibuy = buy;
                 isell = sell;
                 leastBuy = buy;
                 setted = true;
             }
             else
             {
                 if(prices[buy] <= prices[ibuy] && prices[sell] - prices[buy] >= prices[isell] - prices[ibuy])
                     {ibuy = buy; isell = sell;}
                 if(prices[sell] > prices[isell] && prices[buy] > prices[leastBuy])
                     {isell = sell; ibuy = leastBuy;}
                 if(prices[leastBuy] > prices[buy])leastBuy = buy;
             }
         }
         return prices[isell] - prices[ibuy];
     }
 };
@dslztx在评论中找出了上面算法的一个错误,修正如下
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         int len = prices.size();
         if(len <= )return ;
         int i = ;
         int ibuy = , isell = , leastBuy = ; //leastBuy为前面已经扫描过的最低价格
         bool setted = false;
         while(i < len - )
         {
             int buy, sell;
             while(i+ < len && prices[i+] < prices[i])i++;//递减区间
             buy = i++;
             while(i < len && prices[i] >= prices[i-])i++;//递增区间
             sell = i-;
             //此时从prices[buy]~prices[sell]是递增区间
             if(prices[buy] <= prices[ibuy])
             {
                 if(prices[sell] - prices[buy] >= prices[isell] - prices[ibuy])
                 {
                     ibuy = buy;
                     isell = sell;
                 }
             }
             else
             {
                 if(prices[sell] > prices[isell])
                     isell = sell;
             }
             if(prices[buy] > prices[leastBuy])
                 ibuy = leastBuy;
             if(prices[leastBuy] > prices[buy])leastBuy = buy;
         }
         return prices[isell] - prices[ibuy];
     }
 };
算法2:设dp[i]是[0,1,2...i]区间的最大利润,则该问题的一维动态规划方程如下
dp[i+1] = max{dp[i], prices[i+1] - minprices} ,minprices是区间[0,1,2...,i]内的最低价格
我们要求解的最大利润 = max{dp[0], dp[1], dp[2], ..., dp[n-1]} 代码如下:
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         int len = prices.size();
         if(len <= )return ;
         int res = prices[] - prices[], minprice = prices[];
         for(int i = ; i < len; i++)
         {
             minprice = min(prices[i-], minprice);
             if(res < prices[i] - minprice)
                 res = prices[i] - minprice;
         }
         if(res < )return ;
         else return res;
     }
 };
算法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]是最小价格,且他们满足前后顺序关系。代码如下:
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         int len = prices.size();
         if(len <= )return ;
         int res = , currsum = ;
         for(int i = ; i < len; i++)
         {
             if(currsum <= )
                 currsum = prices[i] - prices[i-];
             else
                 currsum += prices[i] - prices[i-];
             if(currsum > res)
                 res = currsum;
         }
         return res;
     }
 };
这个题可以参考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:找到所有价格的递增区间,每个区间内以对低价买入最高价卖出
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         int len = prices.size();
         if(len <= )return ;
         int i = ;
         int res = ;
         while(i < len - )
         {
             int buy, sell;
             //递减区间
             while(i+ < len && prices[i+] < prices[i])i++;
             buy = i++;
             //递增区间
             while(i < len && prices[i] >= prices[i-])i++;
             sell = i-;
             res += prices[sell] - prices[buy];
         }
         return res;
     }
 };
算法2:同上一题构建股票差价数组,把数组中所有差价为正的值加起来就是最大利润了。其实这和算法1差不多,因为只有递增区间内的差价是正数,并且同一递增区间内所有差价之和 = 区间最大价格 - 区间最小价格
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         int len = prices.size();
         if(len <= )return ;
         int res = ;
         for(int i = ; i < len-; i++)
             if(prices[i+]-prices[i] > )
                 res += prices[i+] - prices[i];
         return res;
     }
 };
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]内的最高价格。 本文地址
因此两趟扫描数组就可以解决这个问题,代码如下:
 class Solution {
 public:
     int maxProfit(vector<int> &prices) {
         // IMPORTANT: Please reset any member data you declared, as
         // the same Solution instance will be reused for each test case.
         const int len = prices.size();
         if(len <= )return ;
         int maxFromHead[len];
         maxFromHead[] = ;
         int minprice = prices[], maxprofit = ;
         for(int i = ; i < len; i++)
         {
             minprice = min(prices[i-], minprice);
             if(maxprofit < prices[i] - minprice)
                 maxprofit = prices[i] - minprice;
             maxFromHead[i] = maxprofit;
         }
         int maxprice = prices[len - ];
         int res = maxFromHead[len-];
         maxprofit = ;
         for(int i = len-; i >=; i--)
         {
             maxprice = max(maxprice, prices[i+]);
             if(maxprofit < maxprice - prices[i])
                 maxprofit = maxprice - prices[i];
             if(res < maxFromHead[i] + maxprofit)
                 res = maxFromHead[i] + maxprofit;
         }
         return res;
     }
 };
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3436457.html
LeetCode:Best Time to Buy and Sell Stock I II III的更多相关文章
- leetcode day6 -- String to Integer (atoi) && Best Time to Buy and Sell Stock I II III
		
1.  String to Integer (atoi) Implement atoi to convert a string to an integer. Hint: Carefully con ...
 - LeetCode之“动态规划”:Best Time to Buy and Sell Stock I && II && III && IV
		
Best Time to Buy and Sell Stock I 题目链接 题目要求: Say you have an array for which the ith element is the ...
 - [LeetCode] 递推思想的美妙 Best Time to Buy and Sell Stock I, II, III  O(n) 解法
		
题记:在求最大最小值的类似题目中,递推思想的奇妙之处,在于递推过程也就是比较求值的过程,从而做到一次遍历得到结果. LeetCode 上面的这三道题最能展现递推思想的美丽之处了. 题1 Best Ti ...
 - [Leetcode][JAVA] Best Time to Buy and Sell Stock I, II, III
		
Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a gi ...
 - [leetcode]_Best Time to Buy and Sell Stock I && II
		
一个系列三道题,我都不会做,google之答案.过了两道,第三道看不懂,放置,稍后继续. 一.Best Time to Buy and Sell Stock I 题目:一个数组表示一支股票的价格变换. ...
 - Best Time to Buy and Sell Stock I,II,III [leetcode]
		
Best Time to Buy and Sell Stock I 你只能一个操作:维修preMin拍摄前最少发生值 代码例如以下: int maxProfit(vector<int> & ...
 - Best Time to Buy and Sell Stock I II III
		
Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a gi ...
 - 解题思路:best time to buy and sell stock i && ii && iii
		
这三道题都是同一个背景下的变形:给定一个数组,数组里的值表示当日的股票价格,问你如何通过爱情买卖来发家致富? best time to buy and sell stock i: 最多允许买卖一次 b ...
 - Best Time to Buy and Sell Stock I   II   III  IV
		
一.Best Time to Buy and Sell Stock I Say you have an array for which the ith element is the price of ...
 
随机推荐
- 谷歌浏览器 模拟微信浏览器user-agent
			
1.F12 2.Elments->Emulation Media: Other Network:Mozilla/5.0 (Linux; Android 4.4.4; HM NOTE 1LT ...
 - js实现(全选)多选按钮
			
第一种,全部选中: <html> <head> <title>复选框checked属性</title> <script language=&quo ...
 - Linux shell basic2 cat find tr
			
Cat stands for concatenate. Case 1. When the text files have more blank lines, we want to remove the ...
 - SSH applicationContext.xml文件配置
			
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
 - CentOS 6.5上MySQL安装部署与入门。
			
centos 6.5 yum 安装mysql1. 安装软件:yum install -y mysql-server mysql mysql-devel2.启动服务:service mysqld sta ...
 - 【OpenGL】交互式三次 Bezier 曲线
			
1. 来源 三次贝塞尔曲线就是依据四个位置任意的点坐标绘制出的一条光滑曲线 2. 公式 3. 实现 #include <iostream> #include <math.h> ...
 - SGU 174 Walls
			
这题用并查集来做,判断什么时候形成了环即判断什么时候加入的线段两个端点原先是属于同一集合的.对于一个点,有两个坐标x,y,不好做并查集操作,于是要用map来存储,即做成map<node,int& ...
 - CSU 1116 Kingdoms
			
题意:给你n个城市,m条被摧毁的道路,每条道路修复需要c元,总共有k元,给你每个城市的人口,问在总费用不超过k的情况下 与1号城市相连的城市的最大总人口(包括1号城市) 思路:1号城市是必取的,剩余最 ...
 - eclipse菜单解释及中英对照
			
在使用Eclipse作为开发工具的时候,建议使用英文版本的(直接百度从官网下就行,这里不详细描述,如果有问题,咱们私聊).虽然中文版本的对于和我一样对英文是小白的看起来特别爽,但是公司大多是英文版本的 ...
 - Android组件系列----ContentProvider内容提供者
			
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...