Python每日一练来啦,本文已收录于:《Python每日一练》专栏
此专栏目的在于,帮忙学习Python的小白提高编程能力,训练逻辑思维,持续更新中,欢迎免费订阅!!!
-
1. 问题描述
给定一个长度为 n 的 0 索引整数数组 nums。初始位置在下标 0。
每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:
-
0 <= j <= nums[i] 且
-
i + j < n
返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1。
示例 1:
输入: nums = [2,3,1,1,4] 输出: 2 解释: 跳到最后一个位置的最小跳跃数是 2。 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
-
2. 问题分析
这题我们采用贪心算法来解决,需要找到到达最后一个位置的最小跳跃次数,
关键是在每一步中,选择能够跳得最远的位置作为下一步的候选,记录当前能够
到达的最远位置和下一步能到达的最远位置,当遍历到当前步数能够到达的边界时,增加步数。
-
3. 算法思路
(1)初始化
。jumps = 0: 跳跃次数
。current_step = 0: 当前跳跃能到达的最远位置
。fast_step=0: 所有从当前位置到当前能到达的最远位置中能够到达的最远位置
(2)遍历数组(除了最后一个元素):
-
更新 fast_step = max(fast_step, i + nums[i])
-
如果到达了当前跳跃的边界 i == current_step:
-
增加跳跃次数 jumps++
-
更新 current_step = fast_step
-
如果 current_step >= n-1,提前结束
-
例如: [2,3,1,1,4]
第一步:
索引: 0 1 2 3 4
数组: [2] [3] [1] [1] [4]
↑
起点
索引: 0 1 2 3 4
数组: [2] [3] [1] [1] [4]
↑----↑
当前能跳到的范围: 索引1-2
最远能到: 索引2
-
从索引0可以跳到索引1或2
-
索引1能跳到 1+3=4(直接到终点)
-
索引2能跳到 2+1=3
-
选择跳到索引1(因为从那里能跳得更远)
第二步: 从索引1出发
索引: 0 1 2 3 4
数组: [2] [3] [1] [1] [4]
↑---------↑
当前能跳到的范围: 索引2-4
最远能到: 索引4
-
从索引1可以直接跳到终点索引4
-
完成跳跃
完整的跳跃过程:
跳跃路径: 0 → 1 → 4
步数: 2
图示:
索引: 0 1 2 3 4
[2] [3] [1] [1] [4]
↓ ↓
└────┘ ↑
第1跳 │
↓
└─────────┘
第2跳
贪心策略:
贪心策略:在每一步能到达的范围内,选择能跳得最远的位置
步骤0: 当前位置0,能跳到[1,2]
选择跳到能到达最远的位置(索引1,因为从1能跳到4)
步骤1: 当前位置1,能跳到[2,3,4]
直接跳到终点4
-
时间复杂度: O(n),只需遍历一次数组
-
空间复杂度: O(1),只使用常数空间
-
4. 代码实现
from typing import List
class Solution:
def jump(self, nums: List[int]) -> int:
if len(nums) <= 1:
return 0
jumps = 0
current_step = 0
fast_step = 0
for i in range(len(nums)-1):
if i + nums[i] > fast_step:
fast_step = i + nums[i]
if i == current_step:
jumps += 1
current_step = fast_step
if current_step >= len(nums)-1:
break
return jumps
if __name__ == '__main__':
print(Solution().jump([2,3,1,1,4]))
print(Solution().jump([2,3,0,1,4]))
贪心算法确保了以最少的跳跃次数到达终点,每次都在当前能到达的范围内选择能跳得最远的位置。

被折叠的 条评论
为什么被折叠?



