一个函数解决【LeetCode 买卖股票的最佳时机】系列所有题目!

简介: 一个函数解决【LeetCode 买卖股票的最佳时机】系列所有题目!

题目和题解汇总

之前介绍了【LeetCode 买卖股票的最佳时机】系列一共六道题目,这里把之前的题解还有题目链接汇总一下,方便大家查找。

第一题

LeetCode 121. 买卖股票的最佳时机[1]

每日算法系列【LeetCode 121】买卖股票的最佳时机

第二题

LeetCode 122. 买卖股票的最佳时机 II[2]

每日算法系列【LeetCode 122】买卖股票的最佳时机 II

第三题

LeetCode 123. 买卖股票的最佳时机 III[3]

每日算法系列【LeetCode 123】买卖股票的最佳时机 III

第四题

LeetCode 188. 买卖股票的最佳时机 IV[4]

每日算法系列【LeetCode 188】买卖股票的最佳时机 IV

第五题

LeetCode 714. 买卖股票的最佳时机含手续费[5]

每日算法系列【LeetCode 714】买卖股票的最佳时机含手续费

第六题

LeetCode 309. 最佳买卖股票时机含冷冻期[6]

每日算法系列【LeetCode 309】最佳买卖股票时机含冷冻期

通用解法

上面六道题目中,前四题限制了买卖的次数,第五题加入了手续费,第六题加入了冻结时间。所以我们提出一般性的问题:

给定每天的价格 ,最大买卖次数 ,手续费 ,冻结时间 ,求最大利润。

观察前面六题的代码,我们可以在第四题基础上进行修改,这样代码量比较小。

首先是增加手续费,这个很简单,只需要在  更新时减去一个手续费  就行了。

有点麻烦的是冻结时间。在第六题代码中,增加了一个维度用来保存每一只股票之前(包含)的最大利润,目的是为了获取相隔一个冻结时间之前的股票以前可以获得的最大利润。但是通用情况下不能这么保存,不然的话空间复杂度就变成了  ,极限情况下会爆掉。

解决方法就是,因为对于第  只股票来说,只需要访问它与  之间的数值,那么我们只需要保存  大小的数组就行了。在访问的时候,采用取模的方法,来让数组滚动起来。

还有一些细节,比如如果 ,那么问题就退化为了没有买卖次数限制,也就是第五题和第六题的情况。如果不这样处理的话,按照上面方法做,时间复杂度和空间复杂度都是  ,可能会吃不消。

代码

通用函数

class Solution:
    def solve(self, prices, k=1, fee=0, freeze=0):
        n = len(prices)
        if n == 0 or k == 0: return 0
        limit = 0 if k >= n//2 else 1
        k = 1 if k >= n//2 else k
        dp0 = [-prices[0]] * (k+1)
        dp1 = [[0]*(k+1) for _ in range(freeze+1)]
        for i in range(1, n):
            for j in range(1, k+1):
                dp0[j] = max(dp0[j], dp1[i%(freeze+1)][j-1 if limit else j]-prices[i])
                dp1[i%(freeze+1)][j] = max(dp1[(i-1)%(freeze+1)][j], dp0[j]+prices[i]-fee)
        return max(dp1[(n-1)%(freeze+1)][k], 0)

第一题

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        return self.solve(prices, k=1, fee=0, freeze=0)

第二题

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        return self.solve(prices, k=len(prices), fee=0, freeze=0)

第三题

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        return self.solve(prices, k=2, fee=0, freeze=0)

第四题

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        return self.solve(prices, k, fee=0, freeze=0)

第五题

class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        return self.solve(prices, len(prices), fee, 0)

第六题

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        return self.solve(prices, k=len(prices), fee=0, freeze=1)
相关文章
|
7天前
|
C语言
详解Leetcode中关于malloc模拟开辟二维数组问题,涉及二维数组的题目所给函数中的各个参数的解读
详解Leetcode中关于malloc模拟开辟二维数组问题,涉及二维数组的题目所给函数中的各个参数的解读
6 1
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
13天前
|
算法
leetcode题解:121.买卖股票的最佳时机
leetcode题解:121.买卖股票的最佳时机
10 0
|
19天前
|
容器
【LeetCode刷题】栈和队列题目练习~
【LeetCode刷题】栈和队列题目练习~
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总(4)
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总
|
19天前
|
存储 算法
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总(1)
【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表