IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode系列(一):买卖股票 -> 正文阅读

[数据结构与算法]leetcode系列(一):买卖股票

1. 第一题:122. 买卖股票的最佳时机 II

按照我自己的渐进思路写出四种方法,前三种都是动态规划,最后一种是贪心。

方法1:二维动态矩阵

思路是维护一个n*2的动态矩阵,dp[i][0]表示第i天不持有股票的最大利润,dp[i][1]表示第i天持有股票的最大利润。那么则有转移方程如下:

  • 第i天持有股票的最大利润 = max(保持i-1天持有股票, i-1天不持有股票 + 今天买入)
  • 第i天不持有股票的最大利润 = max(保持i-1天不持有股票, i-1天持有股票 + 今天卖出)?

写出公式就是:

代码如下:

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp =[[0 for i in range(2)] for j in range(n)]
        dp[0][1] = -prices[0]  #买入(持有)
        dp[0][0] = 0    #手上没有股票(不持有)
        for i in range(1,n):
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
        return dp[-1][0]

?python的提交结果:

?方法2:两个一维动态矩阵

转移方程是一样的,代码如下:

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        buy =  [0] * n
        free = [0] * n 
        buy[0] = -prices[0]#买入
        for i in range(1,n):
            buy[i] = max(buy[i-1], free[i-1] - prices[i])
            free[i] = max(free[i-1], buy[i-1] + prices[i])
        return free[-1]

?提交结果,速度有所提升

?方法3:取消数组

通过方法2可以看到,第i次的结果只与i-1次有关,与前面的无关,因此我们可以只保留前一次的记过即可。

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        buy =  -prices[0]
        free = 0 
        for i in range(1,n):
            buy = max(buy, free - prices[i])
            free = max(free, buy + prices[i])
        return free

我们看一下代码,buy = max(buy, free - prices[i])先更新的,free是后更新的。正常来说更新free用到的是前一天的buy,如果buy先更新的话,那么free更新所用的就不是前一天的buy,而是今天的buy。之所以这样没有问题,是因为同一天可以买入再卖出

?方法4:贪心

贪心的方法可以这么理解,我们要求最大利润,就必然要使得卖出的价格高于买入的价格,即prices[latest] > prices[pre]。我们遍历的最小单元跨度为1,即就是对于相邻的区间1,如果prices[i+1] > prices[i],我们就可以买入卖出获利。

这样做的依据同样是:同一天可以买入再卖出。

我们是想一个场景,第一天的价格为7,第二天的价格为1,显然我们不能在第一天买入,在第二天卖出,会亏本的,所以应该在第二天买入。如果以第一天买入的起始,那么实际上第二天买入就= 一天买入并卖出 + 第二天买入。

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        profit = 0
        for i in range(1,n):
            profit += max(0, prices[i] - prices[i-1])
        return profit

?2. 第二题:121. 买卖股票的最佳时机

这一题比上一题稍微简单一点,因为只允许买卖一次,并且不能在同一天买入卖出。

方法1:暴力穷举

嵌套两个循环,速度较慢

方法2:二维动态矩阵

思路是维护一个n*2的动态矩阵,dp[i][0]表示第i天不持有股票的最大利润,dp[i][1]表示第i天持有股票的最大利润。那么则有转移方程如下:

  • 第i天持有股票的最大利润 = max(保持i-1天持有股票,今天第一次买入
  • 第i天不持有股票的最大利润 = max(保持i-1天不持有股票, i-1天持有股票 + 今天卖出)?

红色字体也是与上一题转移方程不同的地方,原因是只能买一次。

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0 for j in range(2)] for i in range(n)]
        dp[0][0] = 0
        dp[0][1] = -prices[0] #持有
        for i in range(1,n):
            dp[i][1] = max(dp[i-1][1],-prices[i]) #第一次买
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]) #卖出去
        return dp[-1][0]

方法3:两个一维动态矩阵

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        buy = [0] * n 
        sell = [0] * n 
        buy[0] = -prices[0]
        for i in range(1,n):
            buy[i]= max(buy[i-1],-prices[i]) #第一次买
            sell[i] = max(sell[i-1], buy[i-1] + prices[i]) #卖出去
        return sell[-1]

方法4:取消数组

    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        buy = -prices[0]
        sell = 0
        for i in range(1,n):
            buy= max(buy,-prices[i]) #第一次
            sell = max(sell, buy + prices[i]) #卖出去
        return sell

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:50:35  更:2022-03-30 18:55:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:50:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码