day28 贪心算法02

86 阅读2分钟

122. 买卖股票的最佳时机 II

文章讲解

思路:

贪心:从第二天开始,计算每天卖出的利润,取每天正利润和,每天利润推导出所有天的最终利润。
1 排除数组<2的
2 计算和前一天的利润差
3 累加正利润
注意:买卖要两天,但是某天可以先售出再买入
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        result = 0 # 最大利润
        if len(prices) < 2:
            return 0
        
        for i in range(1,len(prices)):
            profitDiff = prices[i] - prices[i-1]
            if profitDiff > 0:
                result += profitDiff
            
        return result

55. 跳跃游戏

文章讲解

思路:

每一步更新最大覆盖范围,如果最终范围达到最后一位就true
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        cover = 0
        if len(nums) == 1 :return True # 一个元素时候已经达到最终位置
        i = 0
        # python不支持动态修改for循环中变量,使用while循环代替
        while i <= cover:
            cover = max(cover, i + nums[i]) # 更新覆盖范围
            if cover >= len(nums) - 1:
                return True
            i += 1
            
        return False

45. 跳跃游戏 II

文章讲解

思路:

class Solution:
    def jump(self, nums: List[int]) -> int:
        if len(nums) == 1: return 0

        n = len(nums)
        cur_distance = 0  # 当前覆盖最远距离下标
        result = 0  # 记录走的最大步数
        next_distance = 0  # 下一步覆盖最远距离下标

        for i in range(n-1):
            next_distance = max(next_distance, i + nums[i])
            # 如果当前下标达到了当前覆盖的最远距离,需要走一步
            if i == cur_distance:
                result += 1
                cur_distance = next_distance 
                # 覆盖范围达到最后一个元素,退出
                if next_distance >= n -1: break
        return result

1005. K 次取反后最大化的数组和

文章讲解

思路:

思路:
暴力:从小到大排序,k次优先吧最小的数取反;如果负数数量<k,那么优先对0重复操作;如果没有0,取一个最小的正数来回取反

改进:1 按照绝对值从大到小排列;2 遍历一遍把k各绝对值最大的复数取反,k-- 3 如果k还>0,看看k的奇偶,如果偶数就不用取反了,如果奇数就把最小的数取反(最后一个)3 求和
'''
class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        # 绝对值大到小排序
        nums.sort(key = lambda x:abs(x) , reverse = True)

        # 对k个绝对值最大的负数取反
        for i in range(len(nums)):
            if nums[i] < 0 and k >0:
                nums[i] = -nums[i]
                k -= 1
            elif k == 0: # k=0不用取反了
                return sum(nums)
        
        # k>0且奇数时候,对最后一个元素取反
        if k % 2 == 1:
            nums[-1] = -nums[-1]
        
        # 求和
        return sum(nums)