1:
主要思想:dp(最大和子数组)
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
lenth = len(prices)
if lenth == 1 or lenth == 0:
return 0
newlst = []
for i in range(1,lenth):
newelement = prices[i] - prices[i-1] # 按照算法导论上的思想,把原来存放每一天股票价格的数组,转换成存放股票价格波动的数组
newlst.append(newelement)
# 接下来利用动态规划思想,即考虑newlst这个数组,简称n数组。在n数组上迭代更新
# 最后得到n[j]存放的是,以下标j的元素为结尾的子数组的最大和。
for j in range(1,lenth-1):
newlst[j] = newlst[j] + max(0,newlst[j-1])
res = max(newlst)
# return res >= 0 and res or 0
return res if res > 0 else 0
2:
主要思想:贪心算法
# 由于买卖次数不限,则先采取1中的转换数组,然后遍历newlst,把大于0的元素都加起来就行。
# 其实,newlst大可不必,只要在第一个循环里
# 把所有prices[i] - prices[i-1]大于0的结果统计起来就行
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
lenth = len(prices)
if lenth == 1 or lenth == 0:
return 0
newlst = []
for i in range(1,lenth):
newelement = prices[i] - prices[i-1]
newlst.append(newelement)
res = 0
for j in range(0,lenth-1):
if newlst[j] > 0:
res += newlst[j]
return res
3:
主要思想:dp
# 最多买卖两次
# 看到有一种解法是创建两个dp[]数组(记为dp1、dp2),分别从前向后遍历、从后向前遍历。
# 其中,对于dp1,从前向后遍历,使得dp1[i]记录的是
# 从1到i天可以获得的最大利益,在i这个位置可以选择是否卖出手中股票。
# 对于dp2,从后向前遍历,使得dp2[i]记录的是
# 从i到最后一天中可以获得的最大利益,在i这个位置可以选择是否买股票。
# 最后选择dp1+dp2数组中的最大元素。
#----------
# 下面算法,创建了四个变量,分别代表
# 第一次买股票之后欠了最少多少钱(但由于取的是负数,所以也用max函数)
# 第一次卖股票之后手里最多有多少钱
# 第二次买股票之后最少欠了多少钱(同第一个变量,用max)
# 第二次卖股票之后手里最多有多少钱。
# 显然,第二次买股票之后手里最多有多少钱就是问题的解
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
lenth = len(prices)
if lenth == 0:
return 0
buy1 = -prices[0]
sell1 = 0
buy2 = -prices[0] # sell1 + buy1
sell2 = 0
for i in range(1,lenth):
buy1 = max(buy1,-prices[i])
sell1 = max(sell1,prices[i]+buy1)
buy2 = max(buy2,-prices[i]+sell1)
sell2 = max(sell2,prices[i]+buy2)
return sell2
4:
主要思想:dp + k>prices.length时的考虑以避免超出内测限制
# 第四个跟第三个思路一摸一样,只是k不限制<=2。
# 与上题一样,需要创建 2*k个变量,分别表示
# 第一次买股票之后欠了最少多少钱
# 第一次卖股票之后手里最多有多少钱
# 第二次买股票之后欠了最少多少钱
# 第二次卖股票之后手里最多有多少钱;一直到k...
# 采用这种思想,大概可以通过leetcode上200个样例,但是,当k特别大的时候,内存就超了。
# 事实上,一次买一次卖,必须要用两天,所以当k >= lenth/2的时候,其实就转换成了第二题
# 即,一个就lenth天,k>=lenth/2,其实可以每天都买卖股票
# 也就转换成了一个贪心问题,只要把所有前后两天价格差为正数的情况都算进去就行了。
class Solution(object):
def greedy(self,prices):
res = 0
lenth = len(prices)
res = 0
for i in range(1,lenth):
if prices[i] - prices[i-1] > 0:
res += prices[i] - prices[i-1]
return res
def maxProfit(self, k, prices):
"""
:type k: int
:type prices: List[int]
:rtype: int
"""
lenth = len(prices)
if lenth == 0 or k == 0:
return 0
if k >= lenth/2:
return self.greedy(prices)
res = [[-prices[0],0] for i in range(k)] # return res[k-1][1]
# print(res)
for i in range(1,lenth):
res[0][0] = max(res[0][0],-prices[i])
res[0][1] = max(res[0][1],res[0][0]+prices[i])
for j in range(1,k):
res[j][0] = max(res[j][0],res[j-1][1]-prices[i])
res[j][1] = max(res[j][1],res[j][0]+prices[i])
return res[k-1][1]