这篇page是针对leetcode上的121.买卖股票的最佳时机所写的。小尼先简单的说明一下这道题的意思,就是我们给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。然后我们只能选择某一天买入这只股票,并且选择在之后的一个日子里将它卖出,我们需要给出一个算法算出我所能获得的最大的利润。
小尼一开始使用了比较暴力的解法,但是超时了,小尼先拉一下超时的代码:
- class Solution {
- public int maxProfit(int[] prices) {
- int result = 0;
- for(int i = 0; i < prices.length; i++){
- for(int j = i + 1; j < prices.length; j++){
- result = Math.max(result, prices[j] - prices[i]);
- }
- }
- return result;
- }
- }
这里面的方法运用了两层for循环进行对应的循环的求解,但是这里有很大的问题,就是一但我们给出的数据过多就会造成超时的现象。
接下来,小尼给出动态规划的求解的思路,小尼直接给出动态规划五部曲:
1、确定dp数组以及下标的含义:我们这里设置两层,第一层就是dp[i][0]表示第i天持有的股票所得的最多的现金,记住小尼这里所说的是持有股票所拥有的最多的现金,我们统一将我们最初始的金额定为0,所以我们第一天一旦买入我们的股票,我们的金额就会变负
2、确定递推公式:如果第i天持有股票dp[i][0],那么我们可以由两个状态推过来:
第i-1天就持有股票,我们就一直保持现状,我们所拥有的现金还是第i-1天所拥有的现金
第i天我们就买入了股票,那么我们所得的现金就是买入了今天的股票所得的现金:-prices[i]
同理,我们也需要将dp[i][1]的状态表示出来,我们也是由两个状态所得到的:
第i-1天就不持有股票,我们直接就是跟前一天一样
第i天我们直接卖出我们的股票,所得的现金就是直接利用我们今天的price去进行对应的计算:prices[i] + dp[i - 1][0]
3、dp数组如何进行初始化:由递推公式我们可以得dp[i][0] = max(dp[i - 1][0], -prices[i]);dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0])
4、确定遍历顺序:我们直接就是从前往后进行遍历
5、最后就是导出我们的dp数组
小尼接下来拉一下这道题动态规划的代码:
- class Solution {
- public int maxProfit(int[] prices) {
- if(prices == null || prices.length == 0) return 0;
- int length = prices.length;
- int[][] dp = new int[length][2];
- int result = 0;
- dp[0][0] = -prices[0];
- dp[0][1] = 0;
- for(int i = 1; i < length; i++){
- dp[i][0] = Math.max(dp[i - 1][0],-prices[i]);
- dp[i][1] = Math.max(dp[i - 1][0] + prices[i], dp[i - 1][1]);
- }
- return dp[length - 1][1];
- }
- }