问题描述
小R设计了一款机器人,它的行动受到能量点的限制。机器人需要从第一个位置出发,尝试到达最后一个位置。每个位置上的能量点可以决定机器人最多能向前跳多少步,但如果某个位置的能量为 0,则机器人无法从这个位置再向前移动。
你的任务是判断:机器人是否能从起点跳跃到终点。
输入描述
- n:表示总共有 n 个位置(从 0 到 n−1)。
- array:一个长度为 n 的数组,表示每个位置的能量点数值。
输出描述
- 如果机器人能到达最后一个位置,返回
'TRUE'。 - 如果无法到达最后一个位置,返回
'FALSE'。
示例
示例 1
输入:n = 5, array = [2, 3, 1, 1, 4]
输出:'TRUE'
解释:
- 机器人从第 0 位开始,最多可以跳 2 步。
- 机器人可以跳到第 1 位,此时它最多可以跳 3 步。
- 最终,机器人能够跳到终点。
示例 2
输入:n = 5, array = [3, 2, 1, 0, 4]
输出:'FALSE'
解释:
- 机器人从第 0 位开始,最多可以跳 3 步。
- 它无法跳过第 3 位的能量为 0 的点,因此无法到达终点。
示例 3
输入:n = 6, array = [1, 2, 3, 4, 0, 0]
输出:'TRUE'
解释:
- 机器人从第 0 位开始,能够逐步跳跃,最终到达终点。
解题思路
这一问题可以视作一个经典的跳跃游戏问题,它的核心在于模拟机器人在能量限制下的跳跃行为。为了判断机器人是否能到达终点,我们需要找到一个高效的解决方案。
思路分析
直观思路:递归或回溯
机器人可以尝试从当前点跳到所有可能的下一步位置,并递归判断是否能到达终点。然而,这种思路会导致大量重复计算,效率较低。
优化思路:贪心算法
通过一次遍历,用贪心策略动态维护机器人能到达的最远位置。以下是关键点:
- 定义一个变量
max_reach,表示当前能到达的最远位置。 - 遍历数组的每一个位置 ii,如果当前索引 ii 超过
max_reach,说明无法到达该位置,直接返回'FALSE'。 - 在每个位置上更新
max_reach = max(max_reach, i + array[i]),表示从当前位置 ii 出发,能到达的最远位置。 - 如果
max_reach超过或等于最后一个位置,则返回'TRUE'。
实现代码
以下是使用 Python 实现的解决方案:
def solution(n, array):
max_reach = 0 # 能到达的最远位置
for i in range(n):
if i > max_reach: # 当前点无法到达
return 'FALSE'
max_reach = max(max_reach, i + array[i]) # 更新最远位置
if max_reach >= n - 1: # 能到达最后一个位置
return 'TRUE'
return 'FALSE'
复杂度分析
时间复杂度
算法中只需要遍历数组一次,复杂度为 O(n)。
空间复杂度
只使用了一个变量 max_reach,空间复杂度为 O(1)。
示例分析
示例 1
n = 5, array = [2, 3, 1, 1, 4]
- 初始化
max_reach = 0。 - 遍历第 0 位,
max_reach = max(0, 0 + 2) = 2。 - 遍历第 1 位,
max_reach = max(2, 1 + 3) = 4。 max_reach >= 4,可以到达最后一个位置,返回'TRUE'。
示例 2
n = 5, array = [3, 2, 1, 0, 4]
- 初始化
max_reach = 0。 - 遍历第 0 位,
max_reach = max(0, 0 + 3) = 3。 - 遍历第 1 位,
max_reach = max(3, 1 + 2) = 3。 - 遍历第 3 位,
max_reach = max(3, 3 + 0) = 3。 - 第 4 位无法到达,返回
'FALSE'。
示例 3
n = 6, array = [1, 2, 3, 4, 0, 0]
- 初始化
max_reach = 0。 - 遍历第 0 位,
max_reach = max(0, 0 + 1) = 1。 - 遍历第 1 位,
max_reach = max(1, 1 + 2) = 3。 - 遍历第 2 位,
max_reach = max(3, 2 + 3) = 5。 max_reach >= 5,可以到达最后一个位置,返回'TRUE'。