【LeetCode股票买卖系列:188. 买卖股票的最佳时机 IV | 暴力递归=>记忆化搜索=>动态规划】

news2024/12/23 17:45:55

在这里插入图片描述

🚀 算法题 🚀

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

🚀 算法题 🚀

在这里插入图片描述

🍔 目录

    • 🚗 知识回顾
    • 🚩 题目链接
    • ⛲ 题目描述
    • 🌟 求解思路&实现代码&运行结果
      • ⚡ 暴力法
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 记忆化搜索
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 动态规划
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
    • 💬 共勉

🚗 知识回顾

大家在学习这道题目之前,可以先去看一下买卖股票最佳时机1,再看这个题目就更容易理解了。
博客的地址放到这里了,可以先去学习一下这到题目。

  • 【LeetCode股票买卖系列:121. 买卖股票的最佳时机 | 一次遍历 | 暴力递归=>记忆化搜索=>动态规划】
  • 【LeetCode股票买卖系列:122. 买卖股票的最佳时机 II | 贪心 | 暴力递归=>记忆化搜索=>动态规划】
  • 【LeetCode股票买卖系列:123. 买卖股票的最佳时机 III 暴力递归=>记忆化搜索=>动态规划】

🚩 题目链接

  • 188. 买卖股票的最佳时机 IV

⛲ 题目描述

给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格,和一个整型 k 。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

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

示例 1:

输入:k = 2, prices = [2,4,1]
输出:2
解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
示例 2:

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

提示:

0 <= k <= 100
0 <= prices.length <= 1000
0 <= prices[i] <= 1000

🌟 求解思路&实现代码&运行结果


⚡ 暴力法

🥦 求解思路

  1. 该题目区别于之前学习的最多买卖2次的股票题目,不同的是该题目买卖的次数给我们限制为最多不超过k次。那么该题直接求解就可以了,因为最多买卖2次只是最多不超过k次的特殊情况。
  2. 按照之前的思路,我们按照最多买卖2次,将模型抽离出来,然后做一个特殊化处理,就是不超过k次的结果。接下来我们就来实现一下具体的代码。

🥦 实现代码

class Solution {
    public int maxProfit(int k, int[] prices) {
        int n=prices.length;
        return process(n-1,0,k,prices);
    }

    public int process(int i,int flag,int k,int[] prices){
        if(k<0) return Integer.MIN_VALUE;
        if(i<0) return flag==1?Integer.MIN_VALUE:0;
        if(flag==1) return Math.max(process(i-1,1,k,prices),process(i-1,0,k,prices)-prices[i]);
        return Math.max(process(i-1,0,k,prices),process(i-1,1,k-1,prices)+prices[i]);
    }
}

🥦 运行结果

果然不出我们所料,时间超限了,不要紧张,我们来继续优化它!

在这里插入图片描述


⚡ 记忆化搜索

🥦 求解思路

  1. 因为在递归的过程中,会重复的出现一些多次计算的结果,我们通过开辟一个数组,将结果提前缓存下来,算过的直接返回,避免重复计算,通过空间来去换我们的时间。

🥦 实现代码

class Solution {

    private int[][][] dp;

    public int maxProfit(int k, int[] prices) {
        int n=prices.length;
        dp=new int[n][k+1][2];
        for(int i=0;i<n;i++){
            for(int j=0;j<k+1;j++){
                Arrays.fill(dp[i][j],-1);
            }
        }
        return process(n-1,0,k,prices);
    }

    public int process(int i,int flag,int k,int[] prices){
        if(k<0) return Integer.MIN_VALUE;
        if(i<0) return flag==1?Integer.MIN_VALUE:0;
        if(flag==1) return dp[i][k][flag]=Math.max(process(i-1,1,k,prices),process(i-1,0,k,prices)-prices[i]);
        return dp[i][k][flag]=Math.max(process(i-1,0,k,prices),process(i-1,1,k-1,prices)+prices[i]);
    }
}

🥦 运行结果

我们发现,通过加一个缓存表,还是超限,那我们就继续优化。
在这里插入图片描述


⚡ 动态规划

🥦 求解思路

  1. 有了递归,有了记忆化搜索,接下来就是动态规划了,直接上手。
  2. 此处需要额外注意的是我们在递归和记忆化搜索的时候limit是卖股票,在售出的时候减1,那么动态规划,递推的过程是则相反。

🥦 实现代码

class Solution {

    private int[][][] dp;

    public int maxProfit(int k, int[] prices) {
        int n=prices.length;
        dp=new int[n][k+1][2];
        for(int i=0;i<k+1;i++){
            dp[0][i][1]=-prices[0];
            dp[0][i][0]=0;
        }
        for(int i=1;i<n;i++){
            for(int j=1;j<=k;j++){
                dp[i][j][1]=Math.max(dp[i-1][j][1],dp[i-1][j-1][0]-prices[i]);
                dp[i][j][0]=Math.max(dp[i-1][j][0],dp[i-1][j][1]+prices[i]);
            }
        }
        return dp[n-1][k][0];
    }
}

🥦 运行结果

搞定,简直不要太爽!
在这里插入图片描述


💬 共勉

最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉!

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Hibernate(一)——入门

在之前经常用到操作数据库的框架是Mybatis或者Mybatis-plus。 Hibernate在項目中用过&#xff0c;但没有深入的了解过&#xff0c;所以这次趁着假期把这个框架了解一下。 目录 概念Hibernate和Mybatis的区别Hibernate使用依赖引入Hibernate配置文件XML配置文件详解properties文…

2023 年 五一杯 B 题过程 + 代码(第一问)

文章目录 第一题问题分析PageRank 算法&#xff08;可跳过&#xff09;PageRank 算法修正权重系数 结果各城市链出与链入链出 权重链入 权重 PageRank 算法结果代码 第一题 问题分析 从收货量、发货量、快递数量增长/减少趋势、相关性等多角度考虑&#xff0c;建立数学模型&…

如何使用git更新别人的代码

文章目录 如何使用git更新别人的代码问题说明省流问题示例操作步骤总结总结 如何使用git更新别人的代码 问题说明 当自己git clone别人的代码之后&#xff0c;代码一直停留到本地电脑上&#xff0c;而你就跑了一次程序就搁置了。 后来有一天你想再次运行该代码&#xff0c;但…

可观测性:你的应用健康吗?

一、需求来源 首先来看一下&#xff0c;整个需求的来源&#xff1a;当把应用迁移到 Kubernetes 之后&#xff0c;要如何去保障应用的健康与稳定呢&#xff1f;其实很简单&#xff0c;可以从两个方面来进行增强&#xff1a; 首先是提高应用的可观测性&#xff1b;第二是提高应…

Matplotlib 安装介绍

文章目录 安装步骤 Matplotlib 不止是一个数学绘图库&#xff0c;它也是可视化和分析工具中最流行之一。我们可用其制作简单的图表&#xff0c;如折线图和散点图。 安装步骤 先进入&#xff1a;python官网 跳转到界面&#xff1a; 录入并搜索 下载之前&#xff0c;看一下自…

嵌入式linux学习笔记--虚拟局域网组网方案分享,基于自组zerotier -planet 网络的方案

0. 前言 五一假期期间重新考虑了目前的组网环境&#xff0c;准备对目前的组网进行一个重新的划分。 目前有的资源 ① 两台 服务器&#xff0c;阿里云-深圳&#xff08;5M上行&#xff09;和腾讯云 广州&#xff08;3M上行&#xff09; ② 带动态公网IP的家庭宽带 &#xff08;…

伽马校正的前世今生

关于伽马校正的前因后果&#xff0c;在网上有不同版本的说法&#xff0c;由于年代久远的因素&#xff0c;导致原本很简单的事情越说越复杂。今天我们的目标就是抓住伽马的头&#xff0c;而不是摸一下伽马的尾巴。 一&#xff0c;鱼龙混杂的论调 1&#xff0c;CRT 显示器的物理…

系统集成项目管理工程师下午真题 计算题 及考点 汇总(更新中。。。)

文章目录 2022下半年广东卷 2022下半年广东卷 1、质量保证、质量控制。质量管理方面存在的问题&#xff0c;并给出正确的做法。判断下列选项的正误。 2、下表是一个软件项目在编码阶段各活动的计划和实际完成情况&#xff08;工作量&#xff0c;单位&#xff1a;人天&#xf…

Linux环境下的redis

一&#xff1a;安装与启动 1.下载redis安装包 2.解压&#xff1a;tar –xvf 文件名.tar.gz 3.安装 进入redis目录&#xff08;cd redis-x.x.x/)后&#xff0c;执行make install 命令 4.启动 进入src目录&#xff0c;执行redis-server 此时该界面无法再使用&#xff0c;需要…

Eureka 服务注册源码探秘——图解、源码级解析

&#x1f34a; Java学习&#xff1a;社区快速通道 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年5月2日 &#x1f34a; 点…

NPOI导出word文档中插入公式总结

1. XWPFOMath类 XWPFDocument doc new XWPFDocument(); //创建新行 XWPFParagraph p doc.CreateParagraph(); //创建空的公式 XWPFOMath math p.CreateOMath();通过XWPFParagraph的扩展方法创建 方法名备注CreateAcc();创建XWPFAcc类&#xff0c;实现字符在文字上面的类Cr…

【前端】2.HTML基础知识

文章目录 1. 基本概念1.1 HTML是什么1.2 HTML的作用1.3. 学习导引1.4 开发工具 2. HTML 基础语法2.1 demo2.1.1 HTML 详述2.1.2 HTML标签2.1.3 HTML网页结构2.1.4HTML版本 2.2 常用元素2.3 属性2.4 文本相关语法2.5 链接相关语法2.6 头部相关语法 3. 总结3.1 HTML 基础语法总结…

什么是VLAN?为什么要划分VLAN?

VLAN(Virtual Local Area Network)即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。每个VLAN是一个广播域&#xff0c;VLAN内的主机间可以直接通信&#xff0c;而VLAN间则不能直接互通。这样&#xff0c;广播报文就被限制在一个VLAN内。 一、为…

如何简单快速搭建自己的云对象存储服务(OSS)

简单来说&#xff0c;其实我们只需要有一台服务器&#xff0c;利用服务器的各种资源&#xff0c;搭配其它厂商开发的软件&#xff0c;就能很轻易拥有自己的云对象存储服务。不需要在阿里云上花钱买什么服务&#xff0c;甚至还能自己给别人提供服务&#xff0c;真的是太爽了。 云…

五一创作【Android构建篇】MakeFile语法

前言 对于一个看不懂Makefile构建文件规则的人来说&#xff0c;这个Makefile语法和shell语法是真不一样&#xff0c;但是又引用了部分shell语法&#xff0c;可以说是shell语法的子类&#xff0c;Makefile语法继承了它。 和shell语法不一样&#xff0c;这个更难一点&#xff0…

云原生架构的发展历史

目录 1 单机小型机时代2 垂直拆分3 集群化负载均衡架构4 服务化改造架构5 服务治理6 微服务时代7 服务网格新时期 &#xff08;service mesh&#xff09;7.1 背景7.2 SideCar7.3 Linkerd7.4 istio7.5 什么是服务网格7.6 什么是Service Mesh7.7 CNCF云原生组织发展和介绍7.8 国内…

C++11--线程库的认识

目录 thread 线程的构造方式 相关成员函数 join与detach 线程传参 互斥量mutex mutex Locks 原子性操作库 条件变量 thread 线程的构造方式 它是不支持拷贝构造&#xff0c;赋值的&#xff0c;但是可以支持移动构造&#xff0c;移动赋值。还可以直接创建无参的对象。 …

存储器(一)

目录 一、存储器的分类 1.按介质分类 1.1半导体存储器 1.2磁表面存储器 1.3光盘存储器 2.按存取方式分类 2.1随机存储器(RAM) 2.2只读存储器(ROM) 2.3串行访问存储器 3.按在计算机中的作用分类 ​编辑 二、存储器的层次结构 1.存储器的主要性能指标: 2.存储系统体系…

模式识别是什么意思

模式识别是一种通过分析数据特征、模型、算法等手段&#xff0c;从数据中寻找规律、发现隐藏的模式或结构的技术。通常是从某些对象、场景、过程等方面入手&#xff0c;对数据进行处理&#xff0c;以便于对这些对象、场景、过程进行分类、检测、识别、分割、分析等目的。 模式…

HJ20 密码验证合格程序

写在前面&#xff1a; 题目链接&#xff1a;牛客网 华为机试题 HJ20 密码验证合格程序 题目难度&#xff1a;中等 编程语言&#xff1a;C 一、题目描述 描述 密码要求: 1.长度超过8位 2.包括大小写字母.数字.其它符号,以上四种至少三种 &#xff08;注&#xff1a;其他符号不…