📜  门| GATE CS Mock 2018 |设置 2 |问题 16(1)

📅  最后修改于: 2023-12-03 14:58:22.440000             🧑  作者: Mango

门 | GATE CS Mock 2018 |设置 2 |问题 16

该题目是2018年GATE CS模拟考试第二组的第16道题目。

题目描述

给定一个整数数组,数组中元素表示可以跳过它所在位置的长度。例如,如果在第一个位置赋值为3,则当前位置可以向前跳跃3个位置,这可能会使您跳过1-2个位置,而第3个位置则是下一处。

现在,假设数组中最后一个位置的下标为n-1,您的任务是找到是否存在一种跳跃方案,使您可以从第一个位置跳到最后一个位置。注意,任何时候,您都不应该跳过数组范围之外。

输入

第一行包含一个整数T,表示测试用例的数量。 然后为每个测试用例依次提供以下输入:

第一行包含一个整数N。

第二行包含N个以空格分隔的整数,表示数组arr []中的元素。

输出

对于每个测试用例,请输出单独的一行,其中包含YES / NO,指示是否存在一种跳跃方案从第一个位置跳跃到最后一个位置。

示例

输入 :

 2
 4
 2 1 0 0
 3
 1 2 0

输出 :

NO
YES
解释

对于第一个测试用例,第一个元素是2,这意味着可以跳至第2或第3个元素中的任何一个,但它们都是0,因此它们无法前进。

对于第二个测试用例,第一个元素是1,这意味着我们可以跳到第二个元素,第二个元素是2,这意味着它可以跳到最后的元素,因此在这种情况下是YES。

解法

这个问题可以使用贪心法进行求解。 我们维护最大索引,它表示从当前位置可到达的任何位置的最远距离。 我们递推起始索引i = 0时的最大索引max_index = arr [0] + 0,而不是仅计算出arr [0],因为在i = 0时,我们实际上可以在第1个索引处跳跃前进并到达最大索引,而最大索引表示我们可以跳跃的最远点,我们可以从其中选一个索引进行下一跳跃。

如果最大索引i = 0,我们不能前进,并且返回NO,否则,我们将最大索引更新为max(max_index,arr [i] + i)。 由于我们更新了最大索引,因此,即使在i + 1时它难以前进,但它可以早日到达我们在当前位置可达到的最远距离max_index。

因此,当我们遍历完整个数组后,如果最大索引max_index具有值,那么我们将到达此位置,反之,如果无法到达此位置,则返回NO。

时间复杂度

该算法的时间复杂度为O(n)。

代码
def can_reach_end(arr):
  max_index = arr[0]
  for i in range(len(arr)):
    if i > max_index:
      return False
    max_index = max(max_index, arr[i]+i)
  return True

test_cases = int(input())
for t in range(test_cases):
  n = int(input())
  arr = [int(x) for x in input().split()]
  result = "YES" if can_reach_end(arr) else "NO"
  print(result)