返回
跳跃游戏:进退无忧,畅行无阻
后端
2024-01-24 15:56:38
- 跳跃游戏
给你一个非负整数数组 nums
,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可前进的最大距离。
请你判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步到达下标 1 处,然后跳 3 步到达下标 4 处,最后跳 1 步到达下标 5 处。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,你总会到达下标 3 处,但无法到达下标 4 处。
动态规划解法:
- 定义状态:
dp[i]
表示从第一个下标出发是否能到达下标i
。 - 状态转移方程:
dp[i] = dp[j] && (nums[j] >= i - j)
,其中j
是[0, i-1]
范围内的下标。 - 初始状态:
dp[0] = true
。 - 目标状态:
dp[n-1]
,其中n
是nums
的长度。
贪心解法:
- 定义变量
max_reach
,表示从第一个下标出发能达到的最远下标。 - 遍历
nums
数组,更新max_reach
:max_reach = max(max_reach, i + nums[i])
。 - 判断
max_reach
是否大于等于nums
的长度减一:max_reach >= nums.length - 1
。
代码实现:
def can_jump(nums):
"""
:type nums: List[int]
:rtype: bool
"""
# 动态规划解法
n = len(nums)
dp = [False] * n
dp[0] = True
for i in range(1, n):
for j in range(i):
if dp[j] and nums[j] >= i - j:
dp[i] = True
break
return dp[n-1]
def can_jump_greedy(nums):
"""
:type nums: List[int]
:rtype: bool
"""
max_reach = 0
for i, num in enumerate(nums):
if i > max_reach:
return False
max_reach = max(max_reach, i + num)
return max_reach >= len(nums) - 1
复杂度分析:
- 时间复杂度:动态规划解法的时间复杂度为
O(n^2)
,贪心解法的时间复杂度为O(n)
。 - 空间复杂度:动态规划解法和贪心解法都使用了
O(n)
的空间。