wuyijia

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

代码随想录算法训练营-贪心算法-2|55. 跳跃游戏、45. 跳跃游戏 II、1005. K 次取反后最大化的数组和

55. 跳跃游戏
1. 跳跃的覆盖范围。这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!
2. 贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)
复制代码
 1 class Solution:
 2     def canJump(self, nums: List[int]) -> bool:
 3         cover = 0
 4         if len(nums) == 1: return True
 5         i = 0
 6         # python不支持动态修改for循环中变量,使用while循环代替
 7         while i <= cover:
 8             cover = max(i + nums[i], cover)
 9             if cover >= len(nums) - 1: return True
10             i += 1
11         return False
复制代码

45. 跳跃游戏 II

1. 目标是使用最少的跳跃次数到达数组的最后一个位置。
2. 说明: 假设你总是可以到达数组的最后一个位置。
3. 这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。
  • 如果当前覆盖最远距离下标不是是集合终点,步数就加一,还需要继续走。
  • 如果当前覆盖最远距离下标就是是集合终点,步数不用加一,因为不能再往后走了。
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)
复制代码
 1 class Solution:
 2     def jump(self, nums):
 3         if len(nums) == 1:
 4             return 0
 5         
 6         cur_distance = 0  # 当前覆盖最远距离下标
 7         ans = 0  # 记录走的最大步数
 8         next_distance = 0  # 下一步覆盖最远距离下标
 9         
10         for i in range(len(nums)):
11             next_distance = max(nums[i] + i, next_distance)  # 更新下一步覆盖最远距离下标
12             if i == cur_distance:  # 遇到当前覆盖最远距离下标
13                 ans += 1  # 需要走下一步
14                 cur_distance = next_distance  # 更新当前覆盖最远距离下标(相当于加油了)
15                 if next_distance >= len(nums) - 1:  # 当前覆盖最远距离达到数组末尾,不用再做ans++操作,直接结束
16                     break
17         
18         return ans
复制代码

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

1. 局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。

2. 那么本题的解题步骤为:

  • 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  • 第二步:从前向后遍历,遇到负数将其变为正数,同时K--
  • 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
  • 第四步:求和
  
  • 时间复杂度: O(nlogn)
  • 空间复杂度: O(1)
复制代码
 1 class Solution:
 2     def largestSumAfterKNegations(self, A: List[int], K: int) -> int:
 3         A.sort(key=lambda x: abs(x), reverse=True)  # 第一步:按照绝对值降序排序数组A
 4 
 5         for i in range(len(A)):  # 第二步:执行K次取反操作
 6             if A[i] < 0 and K > 0:
 7                 A[i] *= -1
 8                 K -= 1
 9 
10         if K % 2 == 1:  # 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
11             A[-1] *= -1
12 
13         result = sum(A)  # 第四步:计算数组A的元素和
14         return result
复制代码

 

posted on   小吴要努力  阅读(9)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示