股票买卖问题I、II、III、IV、V、VI

news2024/11/26 0:28:08

力控121、122、123、188、714、309。

买卖股票的第一题

121. 买卖股票的最佳时机

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

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

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

贪心算法

在暴力解法的基础上优化,每次暴力解法都是需要找的之前最小的值,我们用一个下标标定最小值在每次循环后查看是否需要更新最小值。

//暴力枚举 O(N^2)
int maxProfit(vector<int>& prices) {
    int n = (int)prices.size(), ans = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            ans = max(ans, prices[j] - prices[i]);
        }
    }
    return ans;
}
//贪心解法   O(N)
int maxProfit(vector<int>& prices) {
    int mini = INT_MAX;
    int maxprice = 0;
    for (size_t i = 0; i < prices.size(); ++i)
    {
        if (prices[i] > mini)
        {
            maxprice = max(maxprice, prices[i] - mini);
        }
        mini = min(mini, prices[i]);
    }
    return maxprice;
}

 买卖股票的第二题

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

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

返回 你能获得的 最大 利润 。和第一题不同的是,股票的买卖次数没有了限制,但是手中只允许有一只股票。

贪心算法

class Solution {
public:
    int maxProfit(vector<int>& nums) {
        int start=0;
        int end=0;
        int ret=0;
        while(end<nums.size()-1)
        {
            while(end<nums.size()-1&&nums[end]<nums[end+1])
            {
                ++end;
            }
            ret+=nums[end]-nums[start];
            start=end+1;
            end=start;
        }
        return ret;
    }
};

将数组的所有点的都标定在二位坐标图中,会发现,线向上递增的,都是可以获得股票收益的时候。所以我们用双指针的方法标定指针向上趋势的第一个结点和最后一个结点,在相减后就是我们这段区间的获利金额。

买卖股票的第三题

123. 买卖股票的最佳时机 III

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

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

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

动态规划

状态表示:状态转移图

在第i天最大利润:买入状态、可交易状态、冷冻期状态

定义双状态,买入状态与卖出状态:F与G状态。每个状态有3个情况就是交易0、1、2次的最大获利,因为出现多状态,所以需要状态转移图。

定义买入和卖出状态的dp表,因为只能完成2笔交易,所以存在完成0笔最大,1笔最大,2笔最大

vector<vector<int>>f(n,vector<int>(3,MIN));
vector<vector<int>>g(n,vector<int>(3,MIN));

状态转移方程

根据状态变化图可以得出 

//i位天数,j为交易次数 
f[i][j]=max(f[i-1][j],g[i-1][j]-prices[i]);
//f[i-1][j]:由昨天买入到今天买入,天数-1,交易次数不变==什么都不干
//g[i-1][j]-prices[i]:今天把股票买了,所以从昨天得卖出状态最大收益
//减去今天的股票价格,就是今天买入状态的最大收益,状态由卖出->买入状态

g[i][j]=max(g[i-1][j]],f[i-1][j-1]+prices[i]);
//g[i-1][j]: 今天啥也不干,依旧是昨天股票价格,天数-1。
//f[i-1][j-1]+prices[i]:今天把持有股票卖了,所以昨天的由昨天买入状态
//加上今天的卖出的的股票价格,就是今天卖出的最大收益,状态由买入->卖出

//如果g[i][j]=max(g[i-1][j]],f[i-1][j-1]+prices[i]);我们的对齐初始化会
//非常的麻烦,为了i-1不越界需要初始化第一行,为了j-1不越界我们初始化第一列
//初始化第一行也就固定3个数据,初始化了无所谓。
//我们可以先
g[i][j]=g[i-1][j];
//然后判断j-1>=0
if(j-1>=0)
    g[i][j]=max(g[i][j]],f[i-1][j-1]+prices[i]);

初始化

我们需要初始化最开头的一行数据,因为是max取,所以我们直接将f和g首行初始化INT_MIN/2;

为什么要/2,因为最开始的-p[i]可能会导致溢出,所以我们最小值/2就好。

然后定义f[0][0]为-price[0]:第一天买入就是,买入第一天股票

然后定义g[0][0]为0:第一天卖入就是,第一天啥也不干,其实后面的g[i][0]都是0,因为第二天也啥也不干的0次交易的最大也是基础前一天的0,不能继承f[i][0-1]这个非法的东西;

返回值

在返回的时候与f表就无关了,因为f表代表手上由股票,必须把票卖掉才是最大利润。所以在g表中找最后一天结束后最大利润

#define MIN -0x3f3f3f3f
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        vector<vector<int>>f(n,vector<int>(3));
        vector<vector<int>>g(n,vector<int>(3));
        f[0][1]=f[0][2]=MIN;
        g[0][1]=g[0][2]=MIN;

        f[0][0]=-prices[0];
        g[0][0]=0;
        for(int i=1;i<n;++i)
        {
            for(int j=0;j<3;++j)
            {
                f[i][j]=max(f[i-1][j],g[i-1][j]-prices[i]);
                g[i][j]=g[i-1][j];
                if(j-1>=0)
                    g[i][j]=max(g[i][j],f[i-1][j-1]+prices[i]);
            }
        }

        int ret=0;
        for(int j=0;j<3;++j)
        {
            ret=max(ret,g[n-1][j]);
        }
        return ret;
    }
};

买卖股票的第四题

309. 买卖股票的最佳时机含冷冻期

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。

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

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

这其实就是第三题的演变版本

#define MIN -0x3f3f3f3f
class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n=prices.size();
        vector<vector<int>>f(n,vector<int>(k+1,MIN));
        vector<vector<int>>g(n,vector<int>(k+1,MIN));
        f[0][0]=-prices[0];
        g[0][0]=0;
        for(int i=1;i<n;++i)
        {
            for(int j=0;j<k+1;++j)
            {
                f[i][j]=max(f[i-1][j],g[i-1][j]-prices[i]);
                g[i][j]=g[i-1][j];
                if(j-1>=0)
                    g[i][j]=max(g[i][j],f[i-1][j-1]+prices[i]);
            }
        }
        int ret=0;
        for(int j=0;j<k+1;++j)
        {
            ret=max(ret,g[n-1][j]);
        }
        return ret;
    }
};

买卖股票的第五题(冷冻期

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

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

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

动态规划

状态表示:状态转换图

在第i天最大利润:买入状态、可交易状态、冷冻期状态

设置3个dp表:买入dp,可交易dp,冷冻dp,大小设置为股市天数。

用一个二维表吧三个表合并在一起:

  • 0下标买入表    dp[i][0] 第i天时买入状态的最大利润

  • 1下标交易表    dp[i][1] 第i天时交易状态的最大利润

  • 2下标可冷冻表 dp[i][2]第i天时可冷冻状态的最大利润

状态转移方程

根据状态转移图,箭头从前一天的某个状态到当天的某个状态得出:

  1. dp[i][buy]=max(dp[i-1][buy],dp[i-1][Tradable]-price[i]);
  2. dp[i][Tradable]=max(dp[i-1][Tradable],dp[i-1][cooling])
  3. dp[i][cooling]=dp[i-1][buy]+price[i];

初始化

查看转移方程,我们需要初始化第一天的所有情况dp[0][buy]、dp[0][Tradable]、dp[0][cooling]。

dp[0][Buy]=-prices[0];
dp[0][cooling]=0;
dp[0][Tradable]=0;

返回值

返回cooling和Traadble最后的最大一个。

代码

class Solution {
    enum state
    {
        Buy,
        Tradable,
        cooling
    };
public:
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        vector<vector<int>> dp(n,vector<int>(3));
        dp[0][Buy]=-prices[0];
        dp[0][cooling]=0;
        dp[0][Tradable]=0;
        for(int i=1;i<n;++i)
        {
            dp[i][Buy]=max(dp[i-1][Buy],dp[i-1][Tradable]-prices[i]);
            dp[i][cooling]=dp[i-1][Buy]+prices[i];
            dp[i][Tradable]=max(dp[i-1][Tradable],dp[i-1][cooling]);
        }
        return max(dp[n-1][Tradable],dp[n-1][cooling]);
    }
};

买卖股票的第六题(手续费

给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

动态规划

状态表示:状态转换图

在第i天最大利润:买入状态、卖出状态。

2个dp表:

  • send[i]:第i天时候卖出状态下最大的获利情况。

  • buy[i]:第i天时买入状态下最大的获利情况。

状态转移方程

buy[i]=max(buy[i-1],send[i-1]-prices[i]);
//buy[i-1]->buy[i]:昨天处于买入状态,今天依旧处于买入状态
//send[i-1]-prices[i]:昨天是卖出状态,今天买入股票,利减今日股价

send[i]=max(send[i-1],buy[i-1]+prices[i]-fee);
//send[i-1]->sned[i]:昨天处于卖出状态,今日依旧不买股票
//buy[i-1]+prices[i]-fee->send[i]:昨日买入状态,今日卖出股票,获利今日股价,交手续费fee

初始化

buy[0] =-price[0]:第一天买股票。

send[0]=0:第一天不买股票。

返回值

最后一天股票卖出股票的最大值

代码

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int n=prices.size();
        vector<int>send(n);
        vector<int>buy(n);
        buy[0]=-prices[0];
        send[0]=0;
        for(int i=1;i<n;++i)
        {
            buy[i]=max(buy[i-1],send[i-1]-prices[i]);
            send[i]=max(send[i-1],buy[i-1]+prices[i]-fee);
        }
        return send[n-1];
    }
};

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

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

相关文章

tomcat部署jenkins

tomcat部署jenkins 1.简介&#xff1a; Jenkins是一个开源的自动化服务器工具&#xff0c;用于持续集成和持续交付。它能够自动化构建、测试和部署软件项目&#xff0c;提高开发团队的效率和软件质量。 jenkins就是一个整合工具&#xff0c;把代码从git或者其他代码托管平台…

windows10 sockect tcp

1. 在vs下添加ws2_32.lib库 右键【项目】-【属性】-【链接器】-【输入】-【附加依赖项】&#xff0c;进行编辑&#xff0c;添加 ws2_32.lib库&#xff0c;去掉从父级或项目默认设置继承的勾选&#xff0c;如下图所示&#xff1a; 这是因为inet_addr是一个老函数&#xff0c;而…

【MySQL】索引的作用及知识储备

为什么要有索引 索引可以提高数据库的性能。不用加内存&#xff0c;不用改程序&#xff0c;不用调sql&#xff0c;只要执行正确的create indix&#xff0c;查询的速度就可能提高成百上千倍。但相应的代价是&#xff0c;插入&#xff0c;更新&#xff0c;删除的速度有所减弱。 …

【重新定义matlab强大系列十六】求解混合整数线性问题

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

【算法|动态规划No.18】leetcode718. 最长重复子数组

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

数据结构与算法-单链表小练习

&#x1f388;类定义 typedef int ElemType; typedef struct LNode {ElemType data;LNode* next; }LNode; class LinkList { private:LNode* head;public:LinkList();~LinkList();int deletelist(int x);void CreatList_h(int n);void print_evennode();void divide_LinkList(…

『GitHub Actions』部署静态博客指南

前言 之前博主是使用的 Jenkins 实现 vuepress 博客的自动部署与持续交付&#xff0c;但是因为现在迁移服务器到海外&#xff0c;并且服务器配置降低。现在经常出现服务器的 Jenkins 构建过程中 CPU 占用率过高&#xff0c;导致服务器卡死 然后我想的话既然只是部署静态博客&…

基于Java的博客管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

Puppeteer实现上下滚动、打开新Tab、用户数据保存(三)

Puppeteer实现上下滚动、打开新Tab、用户数据保存&#xff08;三&#xff09; Puppeteer实现上下滚动、打开新Tab、用户数据保存&#xff08;三&#xff09;一、实现上下滚动二、打开新Tab三、用户数据保存四、效果演示 一、实现上下滚动 在自动化测试中&#xff0c;我们需要能…

计算机毕业设计选题推荐-springboot 蛋糕甜品店管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

YOLO目标检测——跌倒摔倒数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;公共安全监控、智能家居、工业安全等活动区域无监管情况下的人员摔倒事故数据集说明&#xff1a;YOLO目标检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富。使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含…

SpringBoot面试题1:什么是SpringBoot?为什么要用SpringBoot?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:什么是SpringBoot? Spring Boot 是一个用于快速开发独立的、基于 Spring 框架的应用程序的开源框架。它简化了 Spring 应用的配置和部署过程,使…

稚晖君项目复刻:L-ink门禁卡(1)——环境搭建与第一个项目创建

行文目录 前言其他文章正文开始STM32CubeMX安装STM32CubeMX安装L0的固件支持包Clion安装OpenOCD安装MinGw安装arm-none-eabi-gcc安装Clion配置 创建STM32工程创建STM32CubeMX工程更改芯片型号 参考文献 前言 其实关于稚晖君的L-ink门禁卡在我本科阶段就已经刷过好几次了&#x…

前端页面布局之【响应式布局】

目录 &#x1f31f;前言&#x1f31f;优点&#x1f31f;缺点&#x1f31f;media兼容性&#x1f31f;利用CSS3-Media Query实现响应式布局&#x1f31f;常见的媒体类型&#x1f31f;常见的操作符&#x1f31f;属性值&#x1f31f;设备检测&#x1f31f;响应式阈值选取&#x1f3…

使用vue3+element-ui plus 快速构建后台管理模板

一、安装 vue3 脚手架 npm create vuelatestcd vue-ui-template #切换到刚刚创建好的vue项目根目录中 npm install #下载项目所需要的依赖包 npm run dev #启动运行项目服务项目启动后&#xff0c;默认页面显示如下&#xff1a; 二、安装element-ui plus 官网链接&#xff1a;…

CDN到底有什么魅力,值得网站接入

当谈到提高网站性能和用户体验时&#xff0c;内容分发网络&#xff08;Content Delivery Network&#xff0c;CDN&#xff09;是一项不可忽视的技术。CDN加速已经成为许多在线企业的首选&#xff0c;用以减少加载时间、提高安全性和全球可访问性。本文将深入探讨CDN的原理、工作…

2023-10-14 LeetCode每日一题(只出现一次的数字)

2023-10-14每日一题 一、题目编号 136. 只出现一次的数字二、题目链接 点击跳转到题目位置 三、题目描述 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时…

基于Java的大学生实习管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【LVGL】SquareLine Studio入门基础操作

1.SquareLine Studio基础 在这篇文章中将介绍SquareLine Studio的基础操作、解释如何加载一个项目、布局结构。    启动软件后,可以加载之前的项目、创建项目、加载一个示例。    这里以打开示例audio_mixer为例,可以双击该项目打开或者选中该项目点击右下角的【创建】按…