【Day 3】LeetCode 121. 买卖股票的最佳时机

大家好,我是听雨,是一名跨考计算机专业的研一学生。为提高编程的水平,计划每天刷编程题目。由于我是算法小白,所以开始只能从简单题开始写贴,请大家多多包涵,希望和大家一起进步


题目

  今天的第二题为 力扣121. 买卖股票的最佳时机
在这里插入图片描述

解题思路

一 . 动态规划

  这道题第一次看的时候觉得很简单,准备用左右两个指针来对数组进行交叉遍历,很可惜,200多个测试数据总是有几个数据是错误的,这让我不得不换一种思路。面对这样的题目,动态规划无疑是一种好的想法,于是开始寻找最优子序列的递归关系式。设置dp数组为存放最优子序列的数组, dp[i] 为第 i 天结束的最大利润值。可以想到 dp[i + 1] 是与 dp[i] 和 **prices[i + 1]**是有关系的。最大利润值是通过后天的最大值减去前面几天的最小值来得到的,因此可以想到用一个变量来存放前几天的最小值,并不停迭代这个值。这一点只要在遍历数组的时候就可以做到,记为 m i n min min。那么只需要比较 dp[i]prices[i] - min大小就可以得到 **dp[i + 1]**的取值。递推关系式如下:
d p [ i + 1 ] = m a x { d p [ i ] , p r i c e s [ i ] − m i n } dp[i + 1] = max \{ dp[i],prices[i]-min \} dp[i+1]=max{dp[i],prices[i]min}
  初始值 d p [ 0 ] = 0 dp[0]=0 dp[0]=0

代码如下:

class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int min = prices[0];
        int[] dp = new int[len];
        int res = 0;
        dp[0] = 0;
        for (int i = 1; i < len; i++) {
            min = min < prices[i] ? min : prices[i];
            dp[i] = Math.max(dp[i - 1], prices[i] - min);
            res = res > dp[i] ? res : dp[i];
        }
        return res;
    }
}

结果如下:
在这里插入图片描述

  这样跑出来的结果为似乎拿时间换空间了。

二. 贪心算法

  速度更快的算法,我从题解中看到有大佬用贪心算法来写,于是我复现了一下。若第 1 天价格低于第 2 天价格,即第 1 天成本更低,那么我们一定不会选择在第 2 天买入。进一步的,若在前 i 天选择买入,若想达到最高利润,则一定选择价格最低的交易日买入。考虑根据此贪心思想,遍历价格列表 prices 并执行两步:
  1.更新前 i 天的最低价格,即最低买入成本 ;
  2.更新前 i 天的最高利润 ,即选择前i - 1天最高利润和第 i 天卖出的最高利润 中的最大值
  如下公式所示:
c o s t = { m i n { c o s t , p r i c e s [ i ] } p r o f i t = m a x { p r o f i t , p r i c e s [ i ] − c o s t } ( 第 i 天 ) cost = \begin{cases} min\{ cost,prices[i]\} \\ profit = max\{profit,prices[i] - cost\} \end{cases}\tag{第$i$天} cost={min{cost,prices[i]}profit=max{profit,prices[i]cost}(i)

  初始的 c o s t cost cost值设置为尽量大, p r o f i t profit profit设置为0.

代码如下:

class Solution {
    public int maxProfit(int[] prices) {
        int cost = 100000; //成本
        int res = 0;       //利润
        for(int i = 0; i < prices.length; i ++){
            //更新最小成本
            cost = Math.min(prices[i],cost);
            //更新最大利润
            res = Math.max(res,prices[i] - cost );

        }
        return res;
    }

结果如下:
在这里插入图片描述

总结

  这道题中学到了贪心思想的构建,尽管代码量很少,但真的对我来说没学过几乎没办法想出来。日后还需继续掌握啊!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值