02 买股票的最佳时机 II-20200315
题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
注意事项
- 一次只能持有一只股票,只能操作一只股票。
- 这个相当于给定一个乱序的数组,然后在不改变数组顺序的,降序找到差值最大的组合,将差值相加。若降序被打断,则从新降序计算。
- 价格的数组应该要大于一天,不然买卖没有意思的。
思路一
说白了就是低买高卖,所以,只要买的时候价格比第二天价格低,卖的时候价格比第二天高就可以了。
这道题,可以设置两个指针,former和latter。former指向明天,latter指向今天。
修改经历:
1. 当输入价格数组为[1, 2]时,输出为-1。经检查显示,former的指针放在elif中,并没有被检查到,所以单独拿出来写。(第一次提交)
- 执行用时 :68 ms, 在所有 Python3 提交中击败了57.95%的用户
- 内存消耗 :14.4 MB, 在所有 Python3 提交中击败了9.84%的用户
2. 由于设置了太多的临时变量,比如,指针former和latter,状态位status,总利润 sum_profit等,导致内存消耗太多了,试试看能不能减少点,先把指针省去。(第二次提交)
- 执行用时 :44 ms, 在所有 Python3 提交中击败了89.50%的用户
- 内存消耗 :14.4 MB, 在所有 Python3 提交中击败了9.75%的用户
3. 这个感觉提升不大啊!
- 执行用时 :44 ms, 在所有 Python3 提交中击败了89.50%的用户
- 内存消耗 :14.3 MB, 在所有 Python3 提交中击败了9.84%的用户
心得体会:
我好想考虑的太多了,什么状态啊,看题解上的贪心算法并没有考虑这个。不过在动态规划中,有相似的地方,比方说现金是否在手上。我还考虑了股市只要两天的情况。
最终代码展示:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
sum_profits = 0 # 累计盈利
if len(prices) > 1: # 判断价格天数时候大于1天
status = 0 # 是否买入的状态位,0为未买入,1为已买入
for i in range(0, len(prices)-1):
if status == 0 and prices[i+1] >= prices[i]:
sum_profits -= prices[i]
status = 1
elif status == 1 and prices[i+1] < prices[i]:
sum_profits += prices[i]
status = 0
else:
pass
if status == 1 and i+1 == len(prices) - 1:
sum_profits += prices[i+1]
else:
pass
else:
pass
return sum_profits
思路二
相比于上面的思路一,这种思路参考题解的方法,其实就是贪心算法,每次只考虑连续两天的差价,差价大于零就加上,小于零就pass。这种方法,没有考虑买卖的关系,单纯地从数学的角度考虑。我想,如果有手续费,可能就不是最优的啦。
修改经历:
1. 贪心算法其实和上面差不多,这个内存怎么能降下来呢。
- 执行用时 :40 ms, 在所有 Python3 提交中击败了93.86%的用户
- 内存消耗 :14.3 MB, 在所有 Python3 提交中击败了9.84%的用户
心得体会:
- 根据题目,不要想得太复杂。
最终代码展示:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
sum_profits = 0
for i in range(len(prices)-1):
if prices[i+1] - prices[i] > 0:
sum_profits += prices[i+1] - prices[i]
else:
pass
return sum_profits