python每日一题【剑指 Offer 63. 股票的最大利润】

day19-2022.11.14

题目信息来源
作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm
来源:力扣(LeetCode)

剑指 Offer 63. 股票的最大利润

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

一个垃圾解法,超时了,也没有动态规划,动态规划:定义dp,找到转移方程,初始状态,返回值

class Solution:
    def maxProfit(self, prices) -> int:
        # 暴力遍历,超时了,可以考虑趋势判断
        in_list, out_list, max_idx, min_idx = [], [], 0, 0
        # 判断趋势的标记, 1为找向下的趋势,找买入的时机,0为找向上的趋势,找卖出的时间,收益应该是卖出-买入
        flag = 1
        for i in range(1, len(prices)):
            # 判断向下的趋势
            if flag==1:
                # 找到向下趋势的最小值
                if prices[i]<prices[min_idx]:min_idx = i
                # 向下的趋势被破坏,开始找向上的趋势,max_num=prices[i]
                else:
                    flag = 0
                    max_idx = i
                    in_list.append(min_idx)
            if flag==0:
                # 找到向上趋势的值
                if prices[i]>prices[max_idx]:max_idx = i
                # 向上的趋势被破坏,开始找向下的趋势
                else:
                    flag = 1
                    min_idx = i
                    out_list.append(max_idx)
        result = 0
        for i in out_list:
            for j in in_list:
                if i>j:result = max(result, prices[i]-prices[j])
                else:continue
        return result

题解:

我思路出了一些问题,以为动态规划的转移方程, d p [ i ] dp[i] dp[i] 一般都会和 d p [ i − 1 ] dp[i-1] dp[i1] 有相关性继承,且计算 d p [ i ] dp[i] dp[i] 一般只考虑 p r i c e s [ i ] prices[i] prices[i],思维太僵化了,一定要分析题目,直到最大利润始终是,最大值减去前面的最小值,也就是
d p [ i ] = m a x ( d p [ j − 1 ] , p r i c e s [ i ] − m i n ( p r i c e s [ 0 : i − 1 ] ) ) dp[i]=max(dp[j-1],prices[i]-min(prices[0:i-1])) dp[i]=max(dp[j1],prices[i]min(prices[0:i1]))
前面 d p [ j − 1 ] dp[j-1] dp[j1] 的记忆继承,保证最大值的传承,后面减去的是前面的最小值。之后再减少每次都要处理 m i n ( p r i c e [ 0 : i − 1 ] ) min(price[0:i-1]) min(price[0:i1]) 的时间复杂度,用一个变量保存前面的最小值,又因为最后输出只需要 d p [ i ] dp[i] dp[i] ,用一个变量保存 d p dp dp,减少空间复杂。

class Solution:
    def maxProfit(self, prices) -> int:
        if not prices:return 0
        cost = prices[0]
        profit = 0
        for i in range(1, len(prices)):
            profit = max(profit, prices[i]-cost)
            cost = min(prices[i], cost)
        return profit

我的失败版本,呜呜呜,不是很甘心,改到这个版本,发现我的方法会遗忘最小数,当然最后的测试也过不了

class Solution:
    def maxProfit(self, prices) -> int:
        # dp[i]为当时卖出的利润
        dp = 0
        for i in range(1, len(prices)):
            if prices[i]-prices[i-1]>0:
                if dp==0:
                    dp = prices[i]-prices[i-1]
                    max_num = prices[i]
                    min_num = prices[i-1]
                elif dp==prices[i]-prices[i-1] and min_num>prices[i-1]:
                    min_num, max_num = prices[i-1], prices[i]
                else:
                    cross = min_num-prices[i-1]+prices[i]-max_num
                    add_sum = prices[i]-max_num
                    if cross>add_sum and cross>0:
                        dp = dp + cross
                        min_num, max_num = prices[i-1], prices[i]
                    elif add_sum>cross and add_sum>0:
                        dp = dp + add_sum
                        max_num = prices[i]
        return dp

你可能感兴趣的:(leetcode_python,python,算法,贪心算法,动态规划)