动态规划:leetcode 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机II

news2025/1/23 7:16:56

leetcode 121. 买卖股票的最佳时机

leetcode 122.买卖股票的最佳时机II

leetcode 121. 买卖股票的最佳时机

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

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

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

示例 1:

输入:[7,1,5,3,6,4]

输出:5

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

示例 2:

输入:prices = [7,6,4,3,1]

输出:0

解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

暴力

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int res = 0;
        for(int i = 0; i < prices.size(); i++){
            for(int j = i + 1; j < prices.size(); j++){
                res = max(res, prices[j] - prices[i]);
            }
        }
        return res;
    }
};
  • 时间复杂度:O(n^2)

  • 空间复杂度:O(1)

超时

贪心

因为股票就买卖一次,那么贪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利润。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int res = 0;
        int lowPrice = INT_MAX;
        for(int i = 0; i < prices.size(); i++){
            lowPrice = min(lowPrice, prices[i]);
            res = max(res, prices[i] - lowPrice);
        }
        return res;
    }
};
  • 时间复杂度:O(n)

  • 空间复杂度:O(1)

成功

动态规划

动规五部曲:

  1. 确定dp数组(dp table)以及下标的含义

本题使用一个二维dp数组 dp[i][j] 来表示。

dp[i][0] 表示第i天持有股票所得最多现金,如果买入了股票,那么为负值(-prices[i])。

dp[i][1] 表示第i天不持有股票所得最多现金。

  1. 确定递推公式

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

  • 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]

  • 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i]

那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);

如果第i天不持有股票即dp[i][1], 也可以由两个状态推出来

  • 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]

  • 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]

同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);

  1. 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]);可以看出

其基础都是要从dp[0][0]和dp[0][1]推导出来。

那么dp[0][0]表示第0天持有股票,此时的持有股票就一定是买入股票了,因为不可能有前一天推出来,所以dp[0][0] -= prices[0];

dp[0][1]表示第0天不持有股票,不持有股票那么现金就是0,所以dp[0][1] = 0;

  1. 确定遍历顺序

从递推公式可以看出dp[i]都是由dp[i - 1]推导出来的,那么一定是从前向后遍历。

  1. 举例推导dp数组

以示例1,输入:[7,1,5,3,6,4]为例,dp数组状态如下:

dp[5][1]就是最终结果。因为本题中不持有股票状态所得金钱一定比持有股票状态得到的多。

整体代码如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(), vector<int>(2));
        dp[0][0] -= prices[0];
        dp[0][1] = 0;
        for(int i = 1; i < prices.size(); i++){
            dp[i][0] = max(dp[i - 1][0], -prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
        }
        return dp[prices.size() - 1][1];
    }
};
  • 时间复杂度:O(n)

  • 空间复杂度:O(n)

leetcode 122.买卖股票的最佳时机II

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [7,1,5,3,6,4]

输出: 7

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

示例 2:

输入: [1,2,3,4,5]

输出: 4

解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:

输入: [7,6,4,3,1]

输出: 0

解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

本题和上题的唯一区别是本题股票可以买卖多次了。

区别体现的递推公式上:因为一只股票可以买卖多次,所以当第i天买入股票的时候,所持有的现金可能有之前买卖过的利润。那么第i天持有股票即dp[i][0],如果是第i天买入股票,所得现金就是昨天不持有股票的所得现金减去今天的股票价格 即:dp[i - 1][1] - prices[i], 而不是-prices[i]。

代码如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(), vector<int>(2));
        dp[0][0] -= prices[0];
        dp[0][1] = 0;
        for(int i = 1; i < prices.size(); i++){
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
        }
        return dp[prices.size() - 1][1];
    }
};
  • 时间复杂度:O(n)

  • 空间复杂度:O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/386598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

node版本管理工具nvm

1.标题卸载nvm和node.js 系统变量中删除nvm添加变量&#xff1a;NVM_HOME和NVM_SYMLINK环境变量中 path&#xff1a;删除nvm自动添加的变量 Path %NVM_HOME%;%NVM_SYMLINK%删除自身安装node环境&#xff0c;参考图一图二 图一 图二 2.安装nvm nvm-window下载------https:/…

ES window 系统环境下连接问题

环境问题&#xff1a;&#xff08;我采用的版本是 elasticsearch-7.9.3&#xff09;注意 开始修正之前的配置&#xff1a;前提&#xff1a;elasticsearch.yml增加或者修正一下配置&#xff1a;xpack.security.enabled: truexpack.license.self_generated.type: basicxpack.secu…

对象实例化【JVM】

JVM对象实例化简介/背景一、创建对象的方式1. new2. Class对象的newInstance方法3. Construstor对象的newInstance(xx)方法4. 使用clone方法二、创建对象的步骤1. 判断对象是否已经加载、链接、初始化2. 为对象分配内存3. 处理并发安全问题4. 初始化分配到的空间5. 设置对象的对…

Tech Lead如何引导团队成员解决问题?

作为一个开发团队的Tech Lead&#xff0c;当团队成员向你寻求帮助时&#xff0c;你有没有说过下面这些话&#xff1f; 你别管了&#xff0c;我来解决这个问题你只要。。。就行了你先做其他的吧&#xff0c;我研究一下&#xff0c;然后告诉你怎么做 当我们说这些话时&#xff…

腾讯免费企业邮箱迁移记录

本文记录在重新申请腾讯企业邮箱的过程。 背景 很多年前&#xff0c;将域名latelee.org 迁移到了阿里云&#xff0c;当时因政策原因无法实名&#xff0c;但能使用。去年3月&#xff0c;阿里云提示无法续费&#xff0c;紧急将其转到外面某服务&#xff0c;继续使用&#xff0c;…

IP地址的工作原理

如果您想了解特定设备为何未按预期方式进行连接&#xff0c;或者想要排查网络无法正常工作的可能原因&#xff0c;它可以帮助您了解 IP 地址的工作原理。互联网协议的工作原理与任何其他语言相同&#xff0c;即使用设定的准则进行通信以传递信息。所有设备都使用此协议与其他连…

jq获取同级或者下级的dom节点的操作

1.使用find找到对应的class或者其他 var class_dom1 obj.find(.class名称);或者 find(span .class名称)2.使用添加背景颜色来确定当前的查找位置 class_dom1.css(background,red);3.通过parent来找到它的上级的dom节点 var parent_li_dom1 class_dom1.parent(li.parent_li…

进阶指针——(2)

本次讲解重点&#xff1a; 6. 函数指针数组 7. 指向函数指针数组的指针 8. 回调函数 在前面我们已经讲解了进阶指针的一部分&#xff0c;我们回顾一下在进阶指针(1)我们学过的难点知识点&#xff1a; int my_strlen(const char* str) {return 0; }int main() {//指针数…

创宇盾重保经验分享,看政府、央企如何防护?

三月重保已经迫近&#xff0c;留给我们的准备时间越来越少&#xff0c;综合近两年三月重保经验及数据总结&#xff0c;知道创宇用实际案例的防护效果说话&#xff0c;深入解析为何创宇盾可以在历次重保中保持“零事故”成绩&#xff0c;受到众多部委、政府、央企/国企客户的青睐…

HACKTHEBOX——Irked

nmapnmap -sV -sC -Pn -T4 -oA nmap 10.10.10.117可能是因为网络原因&#xff0c;与目标链接并不稳定&#xff0c;因此添加了参数-Pn&#xff0c;也只扫描了常见的端口扫描可以看到只开启了3个端口&#xff0c;22,80和111。但是在访问web时&#xff0c;页面提示运行着irc因此再…

WebRTC新增FFmpeg视频编解码模块

1、整体描述目前webrtc内置的视频编解码器包括&#xff1a;VP8、VP9、AV1和H264。一般情况下载pc端基本可以满足大部分的需求&#xff0c;但是有时候为了进行编解码器的扩展包括支持H265或者是支持硬件编解码以提升效率时需要新增编解码模块。2、新增外部编码器编码器实现的要点…

亿万级海量数据去重软方法

文章目录原理案例一需求&#xff1a;方法案例二需求&#xff1a;方法&#xff1a;参考原理 在大数据分布式计算框架生态下&#xff0c;提升计算效率的方法是尽可能的把计算分布式话、并行化&#xff0c;避免单节点计算过载&#xff0c;把计算分摊到各个节点。这样解释小白能够…

最新|移动机器人导航定位技术概述

前言目前工业界广泛落地使用的移动机器人&#xff0c;除了应用场景在餐厅、酒店、超市等小范围室内送餐机器人和消毒机器人外&#xff0c;另外一个“大赛道”应用场景就是在工厂、制造装配车间、电站或车站的物流搬运机器人和巡检机器人了。而在最开始&#xff0c;一切都得从AG…

spring cloud gateway (五)

Gateway简介 Spring Cloud Gateway是Spring公司基于Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代Netflix Zuul&#xff0c;其不仅提供统一的路由方式…

java 字典

java 字典 数据结构总览 Map Map 描述的是一种映射关系&#xff0c;一个 key 对应一个 value&#xff0c;可以添加&#xff0c;删除&#xff0c;修改和获取 key/value&#xff0c;util 提供了多种 Map HashMap: hash 表实现的 map&#xff0c;插入删除查找性能都是 O(1)&…

MySQL跨服务器数据映射

MySQL跨服务器数据映射环境准备1. 首先是要查看数据库的federated引擎 开启/关闭 状态2. 打开任务管理器&#xff0c;并重启mysql服务3. 再次查看FEDERATED引擎状态&#xff0c;引擎已启动映射实现问题总结在日常的开发中经常进行跨数据库进行查询数据。 同服务器下跨数据库进…

【SpringCloud】SpringCloud详解之Feign实战

目录前言SpringCloud Feign远程服务调用一.需求二.两个服务的yml配置和访问路径三.使用RestTemplate远程调用(order服务内编写)四.使用Feign远程调用(order服务内配置)五.自定义Feign配置(order服务内配置)六.Feign配置日志(oder服务内配置)七.Feign调优(order服务内配置)八.抽…

STM32之 串口

串口通信串行接口简称串口&#xff0c;也称串行通信接口或串行通讯接口&#xff08;通常指COM接口&#xff09;&#xff0c;是采用串行通信方 式的扩展接口。串行接口&#xff08;Serial Interface&#xff09;是指数据一位一位地顺序传送。其特点是通信线路简 单&#xff0c;只…

Vue基础入门讲义(三)-指令

文章目录1.什么是指令&#xff1f;2.插值表达式2.1.花括号2.2.插值闪烁2.3.v-text和v-html3.v-model4.v-on4.1.基本用法4.2.事件修饰5.v-for5.1.遍历数组5.2.数组角标5.3.遍历对象6.key7.v-if和v-show7.1.基本使用7.2.与v-for结合7.3.v-else7.4.v-show8.v-bind8.1. 属性上使用v…

服务器处理发生异常:java.text.ParseException: Unparseable date

测试上传报文的时候遇见报错 服务器处理发生异常:java.text.ParseException: Unparseable date: “2023/03/03” 错误报文 实际需要的报文 错误原因 上传时间字段&#xff0c;与Date字段数据位数不匹配&#xff0c;Java类型&#xff1a;Date默认带有年月日 时分秒yyyy-mm-dd…