问题描述
小R设计了一款有趣的机器人,它每次移动时至少需要消耗一个能量值。假设当小R为机器人提供了 5 个能量值,它可以选择不动,也可以走 1 步,但它不会走超过 5 步。
小R希望机器人能够走到一个终点,该终点位于 N 个位置的最后一个位置。每个位置上都有一定的能量值,机器人每次消耗当前位置的能量值可以往前走几步,之后可以继续消耗新的位置的能量继续前进。如果某个位置的能量值为 0,机器人将无法再继续行动。
小R想知道,机器人是否有可能通过这些能量值移动到最后一个位置。你能帮他计算一下吗?
解题思路:
-
贪心策略:
- 我们需要遍历整个位置列表,维护一个变量
max_reachable来表示当前位置能到达的最远位置。 - 从当前位置
i开始,更新最远可达位置max_reachable = max(max_reachable, i + array[i]),其中array[i]表示当前位置的能量值,也就是从当前位置最多能跳跃多少步。 - 每次我们检查当前位置
i是否在max_reachable范围内。如果当前位置在范围内,说明机器人可以到达当前位置,并更新最远可达位置。 - 如果某个位置无法到达(即
i > max_reachable),说明机器人无法继续前进,返回'FALSE'。 - 如果我们在遍历过程中发现
max_reachable已经达到或超过目标位置(最后一个位置),则直接返回'TRUE',表示机器人能到达终点。
- 我们需要遍历整个位置列表,维护一个变量
-
判断终点:
- 如果遍历完成并且最终的
max_reachable能到达最后一个位置(n-1),则返回'TRUE',否则返回'FALSE'。
- 如果遍历完成并且最终的
核心思想:
- 通过维护
max_reachable,每次更新最远可达位置。由于我们是在遍历过程中逐步推进,因此该方法符合 贪心算法 的思想:始终选择当前能达到的最远位置,不回头检查已经走过的部分。
解题步骤
-
理解题意:
- 给定一个长度为
n的数组array,其中每个元素表示在该位置上机器人的能量值,即机器人可以从当前位置跳跃的最大步数。 - 目标是判断机器人是否能够从起始位置(位置 0)出发,到达数组的最后一个位置(位置
n-1)。如果可以,返回'TRUE',否则返回'FALSE'。
- 给定一个长度为
-
设定变量:
- 使用一个变量
max_reachable来记录当前机器人能够跳跃到的最远位置。初始化时,max_reachable = 0,因为从起始位置开始时,最远可达位置就是位置 0。
- 使用一个变量
-
遍历数组:
- 遍历数组
array中的每个位置i,检查当前位置是否能够到达。如果当前位置i是可达的(即i <= max_reachable),那么机器人可以到达当前位置,更新max_reachable为max(max_reachable, i + array[i]),表示当前位置的最大跳跃步数加上当前位置的能量值,更新最远可达位置。
- 遍历数组
-
判断当前位置是否不可达:
- 如果在遍历过程中,某个位置
i大于当前的max_reachable,说明当前位置不可达,直接返回'FALSE'。
- 如果在遍历过程中,某个位置
-
判断是否能到达终点:
- 如果在遍历中,
max_reachable达到或超过了目标位置n-1,说明机器人可以到达终点,返回'TRUE'。
- 如果在遍历中,
-
结束遍历后判断:
- 如果遍历结束后,
max_reachable仍然小于目标位置n-1,则说明机器人无法到达终点,返回'FALSE'。
- 如果遍历结束后,
def solution(n, array):
max_reachable = 0
for i in range(n):
if i > max_reachable:
return 'FALSE'
max_reachable = max(max_reachable, i + array[i])
if max_reachable >= n - 1:
return 'TRUE'
return 'FALSE'
代码说明:
max_reachable = 0:表示最初机器人只能在位置 0。for i in range(n):遍历每个位置,检查机器人是否能从当前位置出发。if i > max_reachable:如果当前位置i大于max_reachable,说明机器人无法到达当前位置,返回'FALSE'。max_reachable = max(max_reachable, i + array[i]):更新最远可达位置。如果当前位置的能量值array[i]允许跳得更远,则更新max_reachable。if max_reachable >= n - 1:如果max_reachable达到或超过目标位置n - 1,说明机器人可以到达终点,返回'TRUE'。return 'FALSE':如果遍历结束后,max_reachable仍然无法到达终点,则返回'FALSE'。
时间复杂度:
- 时间复杂度:
O(n),因为我们只遍历了数组一次,每次操作的时间复杂度是常数级别。 - 空间复杂度:
O(1),我们只使用了常数空间存储max_reachable。