领扣-121/122/123/188 最佳买卖时机 Best Time to Buy and Sell MD
| Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 | 
|---|---|---|---|---|
| MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com | 
领扣-121/122 最佳买卖时机 Best Time to Buy and Sell MD
目录
买卖股票的最佳时机 -121
题目
暴力法
贪心算法(波峰波谷法)
优化
买卖股票的最佳时机 II -122
题目
波峰波谷法
波峰波谷法优化
累加法
买卖股票的最佳时机 III -123
动态规划 二维数组(不懂)
动态规划 一维数组(不懂)
买卖股票的最佳时机 IV -188
动态规划(不懂)
买卖股票的最佳时机 -121
数组 贪心算法
题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天的时候买入,在第 5 天的时候卖出,最大利润 = 6-1 = 5 。
      注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
方法声明:
class Solution {
    public int maxProfit(int[] prices) {
    }
}
暴力法
class Solution {
    public int maxProfit(int[] prices) {
        int max = 0;
        for (int i = 0; i < prices.length; i++) {
            for (int j = i + 1; j < prices.length; j++) {
                max = Math.max(max, prices[j] - prices[i]);
            }
        }
        return max;
    }
}
时间复杂度:O(n^2) 
空间复杂度:O(1)
贪心算法(波峰波谷法)
对于这道题,我们很明显能感觉到,不是单纯的找出数组中的最小值和最大值,然后求他们的差的,因为最小值不一定在最大值的前面。
但是也很明显,这道题确实是让我们找最值的,问题出在哪呢?
问题出在,这道题其实是让我们求极小值和极大值的,也即先找出一个波段内的极小值和极大值,然后如果发现另一个更小的极小值后,再找出从此极小值开始后的极大值;最终我们比较的是这些极大值和极小值的差中的最大值。
class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0, temMax = 0, minprice = Integer.MAX_VALUE;
        for (int i = 0; i < prices.length; i++) {
            if (prices[i] < minprice) { //一旦找到更小的值,则开始从此点找极大值
                minprice = prices[i]; //始终存的的是已发现的最小值
                temMax = 0;//重新开始计算差值(这一步是可以忽略的)
            } else {
                temMax = prices[i] - minprice;
                maxprofit = Math.max(maxprofit, temMax);//和之前的最大利润做比较
            }
        }
        return maxprofit;
    }
}
优化
以上逻辑等价于如下形式:
class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0, minprice = Integer.MAX_VALUE;
        for (int price : prices) {
            if (price < minprice) { //一旦找到更小的值,则开始从此点找极大值
                minprice = price; //始终存的的是已发现的最小值
            } else {
                maxprofit = Math.max(maxprofit, price - minprice);//和之前的最大利润做比较
            }
        }
        return maxprofit;
    }
}
也等价于如下形式,虽然这种形式代码量小了一些,但这种形式其实计算多个很多:
class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0, buy = Integer.MAX_VALUE;
        for (int price : prices) {
            buy = Math.min(buy, price);
            maxprofit = Math.max(maxprofit, price - buy);
        }
        return maxprofit;
    }
}
买卖股票的最佳时机 II -122
数组 贪心算法
题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
波峰波谷法
class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0, minprice = Integer.MAX_VALUE, maxprice = Integer.MAX_VALUE;
        boolean findMin = true; //找波谷还是波峰
        for (int i = 0; i < prices.length; i++) {
            if (findMin) { //找波谷
                if (prices[i] < minprice) { //有更低的波谷
                    minprice = prices[i]; //更新购买价格
                    maxprice = prices[i];
                } else { //比波谷的值大,那么我们就找波峰
                    maxprice = prices[i]; //更新卖出价格
                    findMin = false;
                }
            } else { //找波峰
                if (prices[i] > maxprice) { //有更高的波峰
                    maxprice = prices[i]; //更新卖出价格
                } else { //比波峰小,那么我们就在之前卖出,然后在这里买入
                    maxprofit += (maxprice - minprice); //更新收益
                    minprice = prices[i]; //重置所有状态
                    maxprice = prices[i];
                    findMin = true;
                }
            }
        }
        return maxprofit + (maxprice - minprice);//防止最后在找波峰过程中结束,导致没有卖出的问题
    }
}
时间复杂度:O(n) 
空间复杂度:O(1)
波峰波谷法优化
上面的代码实际上有很多运算时可以忽略的,可以优化为如下逻辑
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length <= 1) return 0;
        int i = 0, valley = prices[0], peak = prices[0], maxprofit = 0;
        while (i < prices.length - 1) {
            while (i < prices.length - 1 && prices[i] >= prices[i + 1]) i++; //有更低的波谷
            valley = prices[i]; //更新购买价格
            while (i < prices.length - 1 && prices[i] <= prices[i + 1]) i++; //有更高的波峰
            peak = prices[i]; //更新卖出价格
            maxprofit += peak - valley;
        }
        return maxprofit;
    }
}
累加法
我们不需要跟踪峰值和谷值对应的成本以及最大利润,我们可以直接继续增加数组的连续数字之间的差值,如果第二个数字大于第一个数字,我们获得的总和将是最大利润。这种方法将简化解决方案。
例如:[1, 7, 2, 3, 6, 7, 6, 7] 
与此数组对应的图形是: 
从上图中,我们可以观察到 A+B+C 的和等于差值 D 所对应的连续峰和谷的高度之差。
class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i - 1]) maxprofit += prices[i] - prices[i - 1];
        }
        return maxprofit;
    }
}
买卖股票的最佳时机 III -123
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
动态规划 二维数组(不懂)
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length <= 1) return 0;
        int n = prices.length;
        int[][] g = new int[n][3], l = new int[n][3];
        for (int i = 1; i < n; i++) {
            int diff = prices[i] - prices[i - 1];
            for (int j = 1; j <= 2; j++) {
                l[i][j] = Math.max(g[i - 1][j - 1] + Math.max(diff, 0), l[i - 1][j] + diff);
                g[i][j] = Math.max(l[i][j], g[i - 1][j]);
            }
        }
        return g[n - 1][2];
    }
}
动态规划 一维数组(不懂)
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length <= 1) return 0;
        int n = prices.length;
        int[] g = new int[3], l = new int[3];
        for (int i = 0; i < n - 1; i++) {
            int diff = prices[i+1] - prices[i ];
            for (int j = 2; j >= 1; j--) {
                l[j] = Math.max(g[j - 1] + Math.max(diff, 0), l[j] + diff);
                g[j] = Math.max(l[j], g[j]);
            }
        }
        return g[2];
    }
}
买卖股票的最佳时机 IV -188
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。 
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
方法声明
class Solution {
    public int maxProfit(int k, int[] prices) {
    }
}
动态规划(不懂)
class Solution {
    public int maxProfit(int k, int[] prices) {
        if (prices == null || prices.length <= 1) return 0;
        int n = prices.length;
        if (k >= n) return maxProfit(prices);
        int[] g = new int[k + 1], l = new int[k + 1];
        for (int i = 0; i < n - 1; i++) {
            int diff = prices[i + 1] - prices[i];
            for (int j = k; j >= 1; j--) {
                l[j] = Math.max(g[j - 1] + Math.max(diff, 0), l[j] + diff);
                g[j] = Math.max(l[j], g[j]);
            }
        }
        return g[k];
    }
    public int maxProfit(int[] prices) {
        int maxprofit = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i - 1]) maxprofit += prices[i] - prices[i - 1];
        }
        return maxprofit;
    }
}
2016-12-29 
2018-12-16
领扣-121/122/123/188 最佳买卖时机 Best Time to Buy and Sell MD的更多相关文章
- 121. 122. 123. 188. Best Time to Buy and Sell Stock *HARD* 309. Best Time to Buy and Sell Stock with Cooldown -- 买卖股票
		
121. Say you have an array for which the ith element is the price of a given stock on day i. If you ...
 - Leetocode7道买卖股票问题总结(121+122+123+188+309+901+714)
		
题目1----121. 买卖股票的最佳时机I: 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/ 给定一个数组, ...
 - leetcode 121 122  123 . Best Time to Buy and Sell Stock
		
121题目描述: 解题:记录浏览过的天中最低的价格,并不断更新可能的最大收益,只允许买卖一次的动态规划思想. class Solution { public: int maxProfit(vector ...
 - LeetCode No.121,122,123
		
No.121 MaxProfit 买卖股票的最佳时机 题目 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你 ...
 - 关于股票最佳买卖时机的lintcode代码
		
class Solution {public: /** * @param prices: Given an integer array * @return: Maximum pr ...
 - LeetCode(123):买卖股票的最佳时机 III
		
Hard! 题目描述: 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你必 ...
 - [LeetCode] Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期
		
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
 - [LeetCode] 121. 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 ...
 - [LeetCode] 122. Best Time to Buy and Sell Stock II 买卖股票的最佳时间 II
		
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
 
随机推荐
- 【转载】okhttp源码解析
			
转自:http://www.open-open.com/lib/view/open1472216742720.html https://blog.piasy.com/2016/07/11/Unders ...
 - GeneXus项目启动
			
使用GeneXus产品开发项目时,在开始,有一些属性我会经常改一下.我现在使用的GeneXus版本是GeneXus U3,由于在做手机应用的开发,所以一般使用最新的版本,老外那边差不多两个月会有一个u ...
 - 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
			
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2792 Solved: 1388 Description 小 ...
 - android 启动流程
			
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha adb shell 后 用 ps 命令 回车 可以看到 运行的进程. 如下结果: ct ...
 - Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement
			
1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...
 - maven搭建企业级多模块项目
			
1.创建一个maven项目 选择pom 完成 2.创建模块 项目右键选择module,创建模块.创建子模块 其余的打包时都为jar 地址:https://github.com/LeviFromCN/m ...
 - hdu 4790 Just Random
			
思路:对于a<=x<=b,c<=y<=d,满足条件的结果为ans=f(b,d)-f(b,c-1)-f(a-1,d)+f(a-1,c-1). 而函数f(a,b)是计算0<= ...
 - 零配置文件搭建SpringMvc
			
零配置文件搭建SpringMvc SpringMvc 流程原理 (1)用户发送请求至前端控制器DispatcherServlet:(2) DispatcherServlet收到请求后,调用Handle ...
 - Problem G: 深入浅出学算法008-求佩尔方程的解
			
Description 求关于x y的二次不定方程的解 x2-ny2=1 Input 多组输入数据,先输入组数T 然后输入正整数n(n<=100) Output 对于每组数据输出一行,求y< ...
 - bozj  1449/2895: 球队预算  -- 费用流
			
2895: 球队预算 Time Limit: 10 Sec Memory Limit: 256 MB Description 在一个篮球联赛里,有n支球队,球队的支出是和他们的胜负场次有关系的,具体 ...