机器人能量冒险(中)

107 阅读5分钟

问题描述

小R设计了一款有趣的机器人,它每次移动时至少需要消耗一个能量值。假设当小R为机器人提供了 5 个能量值,它可以选择不动,也可以走 1 步,但它不会走超过 5 步。
小R希望机器人能够走到一个终点,该终点位于 N 个位置的最后一个位置。每个位置上都有一定的能量值,机器人每次消耗当前位置的能量值可以往前走几步,之后可以继续消耗新的位置的能量继续前进。如果某个位置的能量值为 0,机器人将无法再继续行动。
小R想知道,机器人是否有可能通过这些能量值移动到最后一个位置。你能帮他计算一下吗?

解释代码

小 R 设计了一款机器人,并且给它提供了一定数量的能量值(这里是 5 个能量值),这个能量值是机器人用来移动的 “资源”,每次移动至少要消耗 1 个能量值。

移动规则

  • 可选移动方式:机器人在拥有能量值的情况下,可以选择不动,也可以选择走 1 步,但它移动的步数有上限,不能超过所拥有能量值的数量(比如有 5 个能量值时,最多走 5 步)。
  • 能量消耗与前进方式:机器人处于每个位置时,该位置上有特定的能量值。它消耗当前位置的能量值,就能根据消耗的能量值数量往前走相应的步数。然后到达新位置后,又可以消耗新位置的能量值继续前进。例如,当前位置能量值是 3,机器人消耗这 3 个能量值就可以往前走 3 步,到达新位置后再看新位置的能量值情况决定后续移动。
  • 限制条件:如果某个位置的能量值为 0,那么机器人在这个位置就无法再依靠消耗该位置能量值来继续行动了,也就意味着它可能会被困在这个位置无法到达终点。

我给出的代码:

def solution(n, array):
    if n == 0:
        return 'FALSE'

    max_reachable = 0

    for i in range(n):
        if i > max_reachable:
            # If we can't reach this index, exit early
            return 'FALSE'

        # Update the maximum reachable index
        max_reachable = max(max_reachable, i + array[i])

        # If we've reached (or exceeded) the last index, we can stop
        if max_reachable >= n - 1:
            return 'TRUE'

    return 'FALSE'


if __name__ == "__main__":
    # Test cases
    print(solution(5, [2, 3, 1, 1, 4]) == "TRUE")  # Expected output: TRUE
    print(solution(5, [3, 2, 1, 0, 4]) == "FALSE")  # Expected output: FALSE
    print(solution(6, [1, 2, 3, 4, 0, 0]) == "TRUE")  # Expected output: TRUE

代码解释

函数定义与初始条件判断

def solution(n, array): 
    if n == 0: 
        return 'FALSE'
  • 定义了一个名为 solution 的函数,它接受两个参数:n 表示位置的总数(也就是数组 array 的长度),array 是一个列表,其中每个元素表示对应位置上的能量值(根据前面的问题描述,该能量值决定了机器人从该位置能前进的步数)。
  • 如果 n 等于 0,意味着没有位置可供机器人移动,此时直接返回 'FALSE',表示机器人无法到达终点(因为根本就不存在终点位置)。

初始化最大可到达位置索引

max_reachable = 0
  • 创建了一个变量 max_reachable,并初始化为 0。这个变量将用于记录在遍历过程中,机器人能够到达的最远位置的索引。

遍历位置数组并更新最大可到达位置

    for i in range(n):
        if i > max_reachable:
            # If we can't reach this index, exit early
            return 'FALSE'

        # Update the maximum reachable index
        max_reachable = max(max_reachable, i + array[i])

        # If we've reached (or exceeded) the last index, we can stop
        if max_reachable >= n - 1:
            return 'TRUE'
  • 通过一个循环遍历位置数组 array,循环变量 i 从 0 到 n - 1,代表每个位置的索引。
  • 在每次循环中,首先进行一个判断:如果当前位置索引 i 大于 max_reachable,这意味着按照之前的移动规则,机器人无法到达当前这个位置,那么就可以直接返回 'FALSE',因为已经确定机器人无法到达终点了。
  • 接着,更新 max_reachable 的值。通过取当前的 max_reachable 和 i + array[i] 中的最大值来更新 max_reachable。这里的 i + array[i] 表示从当前位置 i 出发,根据当前位置的能量值 array[i] 能够到达的最远位置索引。例如,如果当前在位置 3(i = 3),该位置的能量值是 2(array[3] = 2),那么从这个位置出发能够到达的最远位置就是 3 + 2 = 5,所以要比较这个值和之前记录的 max_reachable,取较大者作为新的 max_reachable
  • 最后,再进行一个判断:如果 max_reachable 已经大于等于 n - 1,这说明机器人已经能够到达或者超过最后一个位置(终点位置),此时就可以返回 'TRUE',表示机器人有可能通过这些能量值移动到最后一个位置。
  • 所使用的算法

这段代码使用的是一种贪心算法(Greedy Algorithm)。

贪心算法的基本思想是在对问题求解时,总是做出在当前看来是最好的选择。在这个具体的代码中:

  • 在每次遍历位置时,都选择当前位置能够到达的最远位置作为新的最大可到达位置(通过 max_reachable = max(max_reachable, i + array[i]) 这一步实现),而不考虑后续可能出现的更优解。也就是说,在每一步都 “贪心” 地想要尽可能地扩大可到达的范围。

  • 然后根据这个不断更新的最大可到达位置来判断是否能够到达终点。如果在某个时刻发现无法到达下一个位置(i > max_reachable),或者最终成功到达了终点(max_reachable >= n - 1),就可以得出最终的结论。

通过这种贪心的策略,代码能够相对高效地判断出机器人是否有可能利用给定的能量值分布移动到最后一个位置,而不需要去穷举所有可能的移动路径组合,从而降低了时间复杂度。