代码随想录Day_49打卡

news/2024/7/7 20:26:03

①、买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

事例:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

思路:

        ①、贪心算法:遍历股票价值,边记录当前范围内的最小值(购入时刻),然后计算当天利润(卖出时刻),求得最大值即可。

代码:

 public int maxProfit(int[] prices) {
        if(prices.length == 1) return 0;
        int minPrice = prices[0];
        int res = 0;
        for(int i = 1;i < prices.length;i++){
            minPrice = Math.min(minPrice,prices[i]);
            int profit = prices[i] - minPrice;
            res = Math.max(res,profit);
        }
        return res;
    }

           ②、动态规划:当天股票只有两种状态,持有/不持有。维持持有状态:当天购入,则有前一天不持有状态减去当天价值,或者直接维持前一天的持有状态,即不卖股票。维持不持有状态:当前卖出,则由前一天的持有状态加上当天价值,或者维持前一天的不持有状态。由于这道题是只卖出一次,故持有和不持有股票的状态只能互相转变一次,即第一次持有股票只能为0 - 当天价值。

动态规划:

        dp定义及含义:dp为一个二维数组,dp[i][0]表示第i天持有股票的最大金额,dp[i][1]表示第i天不持有股票的最大金额

        状态转移方程:dp[i][0] = Math.max(dp[i - 1][0],-price[i])        dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] + price[i])

        初始化:dp[0][0] = -price[0] dp[0][1] = 0

        遍历顺序:正序遍历股票赋值即可

        dp[price.length - 1][1]即为最大利润

代码:

public int maxProfit(int[] prices) {
        // if(prices.length == 1) return 0;
        // int minPrice = prices[0];
        // int res = 0;
        // for(int i = 1;i < prices.length;i++){
        //     minPrice = Math.min(minPrice,prices[i]);
        //     int profit = prices[i] - minPrice;
        //     res = Math.max(res,profit);
        // }
        // return res;

        //动态规划
        if(prices.length == 1) return 0;
        int[][] dp = new int[prices.length][2];
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for(int i = 1;i < prices.length;i++){
            dp[i][0] = Math.max(dp[i - 1][0],-prices[i]);
            dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] + prices[i]);
        }
        return dp[prices.length - 1][1];
    }

②、买卖股票的最佳时机Ⅱ

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

事例:

输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
     总利润为 4 + 3 = 7 。

思路:

        使用动态规划,与上一题一致,这次是多次买卖,故持有状态可以由前一天不持有股票状态 - 当前价值获得。

动态规划:

        dp定义及含义:dp为一个二维数组,dp[i][0]表示第i天持有股票的最大金额,dp[i][1]表示第i天不持有股票的最大金额

        状态转移方程:dp[i][0] = Math.max(dp[i - 1][0],dp[i - 1][1] - price[i])        dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] + price[i])

        初始化:dp[0][0] = -price[0] dp[0][1] = 0

        遍历顺序:正序遍历股票赋值即可

        dp[price.length - 1][1]即为最大利润

代码:

public int maxProfit(int[] prices) {
        //贪心算法 从第二天开始记录每两天的利润 累加正利润
        // int res = 0;
        // for(int i = 1;i < prices.length;i++){
        //     res += Math.max(prices[i] - prices[i - 1],0);
        // }
        // return res;

        //动态规划 dp[i][0] 表示第i天持有股票的金额 dp[i][1] 表示第i天不持有股票的金额
        int[][] dp = new int[prices.length][2];
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for(int i = 1;i < prices.length;i++){
            dp[i][0] = Math.max(dp[i - 1][0],dp[i - 1][1] - prices[i]);
            dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] + prices[i]);
        }
        return dp[prices.length - 1][1];
    }

参考:代码随想录 (programmercarl.com)


http://lihuaxi.xjx100.cn/news/1496651.html

相关文章

生成SSL/TLS 自签名证书

可通过以下两种方式获取相关 SSL/TLS 证书&#xff1a; 自签名证书&#xff1a;即使用自己签发的证书&#xff0c;由于自签名证书存在较多的安全隐患&#xff0c;因此只建议用于测试验证环境。 申请或购买证书&#xff1a;您可以向 Let’s Encrypt (opens new window)或华为云…

算法工程师需要会的docker命令

查看镜像 docker images查看容器 docker ps 进入容器 docker exec -it 容器ID bash容器ID可以输入部分或者全部

Vue生命周期(详细)

生命周期 图&#xff1a; 可以理解vue生命周期就是指vue实例从创建到销毁的过程&#xff0c;在vue中分为8个阶段&#xff1a;创建前/后&#xff0c;载入前/后&#xff0c;更新前/后&#xff0c;销毁前/后。 一、创建&#xff08;实例&#xff09; 1、beforeCreate&#xff1a…

Redis发布订阅

Redis发布订阅 Redis 发布订阅(pub/sub)是一种 消息通信模式&#xff1a;发送者(pub)发送消息&#xff0c;订阅者(sub)接收消息。 Redis 客户端可以订阅任意数量的频道。 订阅/发布消息图&#xff1a; 下图展示了频道 channel1 &#xff0c; 以及订阅这个频道的三个客户端 —…

剑指Offer62.圆圈中最后剩下的数字 C++

1、题目描述 0,1,,n-1这n个数字排成一个圆圈&#xff0c;从数字0开始&#xff0c;每次从这个圆圈里删除第m个数字&#xff08;删除后从下一个数字开始计数&#xff09;。求出这个圆圈里剩下的最后一个数字。 例如&#xff0c;0、1、2、3、4这5个数字组成一个圆圈&#xff0c;从…

ExpressLRS开源之接收机固件编译烧录步骤

ExpressLRS开源之接收机固件编译烧录步骤 1. 源由2. 编译步骤2.1 推荐源代码指定方案2.2 方法一&#xff1a;ELRS Configurator步骤一&#xff1a;下载ELRS Configurator工具步骤二&#xff1a;安装ELRS Configurator工具步骤三&#xff1a;使用ELRS Configurator工具进行配置步…

java遇到java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver该如何解决

普通的Java项目&#xff0c;利用servlet实现登录页面跳转出现下列问题。该如何解决&#xff1f;&#xff1f;&#xff1f; 首先你要先加载驱动&#xff0c;idea通过项目结构添加的依赖包是无法正常加载驱动的。我们要在 WEB-INF目录下建立lib目录在lib目录下添加MySQL驱动。

22道Mysql面试真题和答案

本专栏记录Java后端开发相关的面试题&#xff0c;欢迎大家阅读专栏的其他文章。 1.请介绍下联合索引的最左匹配原则 建立一个联合索引&#xff08;a&#xff0c;b&#xff0c;c&#xff09;&#xff0c;相当于建立多个索引&#xff08;a&#xff09;&#xff08;a&#xff0c;…