当前位置: 首页 > 知识库问答 >
问题:

以奇偶跳转序列到达数组末尾

邵宏达
2023-03-14

我试图理解一个Python解决方案,它似乎使用了动态编程。我能够遵循大部分解决方案,但我正在努力使解决方案真正正规化。

问题陈述如下:

您将获得一个整数数组A。从某个起始索引,您可以进行一系列跳转。(第一、第三、第五……)序列中的跳转称为“奇数”编号跳转,以及(第2、第4、第6、…)序列中的跳转称为偶数跳转。

你可以从indexi跳转到index j(withi

>

在偶数跳转(即跳转2, 4, 6, ...),你跳转到索引j使得A[i]

可能的情况是,对于某些索引i没有合法的跳转。

如果从该索引开始,您可以通过跳几次(可能是0次或多次)到达数组的末尾,则起始索引是好的

我们要求您返回良好的起始索引数。

下面我展示了一些作者已经发布的Python解决方案。我了解它是如何构建oddnextevennext的,以及这些数组在技术上所包含的内容(通过奇数或偶数跳转从该索引跳转到的索引位置)。我不明白的是最后一个循环是如何工作的,以及它背后的精确动态规划公式是什么。

def odd_even_jumps(self, A):
    N = len(A)

    def make(B):
        ans = [None] * N
        stack = []  # invariant: stack is decreasing
        for i in B:
            while stack and i > stack[-1]:
                ans[stack.pop()] = i
            stack.append(i)
        return ans

    B = sorted(range(N), key = lambda i: A[i])
    oddnext = make(B)
    B.sort(key = lambda i: -A[i])
    evennext = make(B)

    odd = [False] * N
    even = [False] * N
    odd[N-1] = even[N-1] = True

    # Why does this loop start from the end? 

    for i in range(N-2, -1, -1):
        if oddnext[i] is not None:
            odd[i] = even[oddnext[i]]
        if evennext[i] is not None:
            even[i] = odd[evennext[i]]

    return sum(odd)

共有2个答案

凌联
2023-03-14

每次迭代,你检查这个索引是否有一个奇数跳跃,如果它检查跳跃目的地,如果你在目的地的位置,并且有一个偶数跳跃,你能到达终点吗,如果是这样,这个奇数索引值应该是真的

然后检查相同的偶数(我有偶数跳转吗?它的dest是索引,在奇数中为true?,将偶数值设置为true)

然后返回奇数个真值,因为第一次跳转是奇数

詹弘毅
2023-03-14

算法的第一部分识别输入数组的任何给定索引,使用奇数(oddNext)或偶数(evenNext)跳转可以跳转到哪里。某些索引填充有None,因为您不能从它们进行任何合法(偶数或奇数)跳转。

获得此信息后,要回答您的问题,请注意以下几点:

  • 任何可以合法跳转到好索引的索引都必须是一个好索引(你可以“重新使用”那个好索引的解决方案以达到最后)
  • 输入数组的最后一个索引总是一个好索引(即你已经到达了终点)

因此,您可以从数组的末尾向后移动,通过检查它们是否会跳转到您已经确定为好(或不好)索引的索引来识别好的索引。

请注意,这是一个动态编程计算,因为您正在建立良好索引之间的循环关系,并在数组中向后移动时利用它(也就是说,您正在以所谓的“自下而上”的方式解决动态编程子问题,根据它们的依赖性结构)。

需要注意的一点是,该算法计算每个位置和每个可能的跳转类型的索引是否良好(即我们完全填充奇数偶数数组)。这是因为,当您在动态编程计算中迭代时,数组的不同起点可能需要从该索引进行奇数或偶数跳跃,即使从任何特定索引开始时,您只能根据问题陈述。

那很好。在动态规划中,一个人通常会解决所有的子问题,即使原始问题的解决方案并不依赖于所有子问题。请注意,这也是为什么最后您只关心odd数组中的哪些索引是好索引的原因。偶数数组只是填充奇数数组的动态编程框架的一部分。

 类似资料:
  • 我得到了一个值大于或等于0的整数数组,例如:[5,6,0,4,2,4,1,0,0,4] 我被要求实现一种算法,以从索引0开始的最短“跃点”数遍历数组,其中遍历定义如下: - 如果我选择跳到索引3,它包含值4,我可以从我当前的索引(3)下一次跳到4个点-所以我现在考虑索引4到7作为序列中的下一步。 我的算法必须确定一个最小跳数解,但可以在具有相同跳数的解中任意选择。 对于本示例,以下内容将是有效输出

  • 我有一个“使用递归到达数组末尾的最小跳跃次数”的代码。但我无法打印序列。(vector vec中没有可打印的内容) 如有任何帮助,将不胜感激。 说明: 我想以最小跳跃从数组的第一个元素(即2)到达最后一个元素(即4) 跳转的方式: 第一个元素是2。这意味着我最多可以在阵列中进行2次跳跃。如果我跳第一步,那么我可以跳到第二个元素(即3),或者如果我跳第二步,那么我可以跳到第三个元素(即1) 第二个元

  • 我们有一个偶数放置排序和奇数放置排序的数组,这意味着偶数索引的子数组被排序,奇数索引的子数组被排序。例如-{1,4,2,7,4,18,5,19,20}两个排序的子数组是{1,2,4,5,20}和{4,7,18,19}-一组有偶数索引,另一组有奇数索引。有没有一种方法可以用O(1)空间复杂度和O(n)时间对整个数组进行排序?

  • 题目描述 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。 分析与解法 最容易想到的办法是从头扫描这个数组,每碰到一个偶数,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,然后把该偶数放入这个空位。由于每碰到一个偶数,需要移动O(n)个数字,所以这种方法总的时间复杂度是O(n^2

  • 本文向大家介绍程序查找在Python中达到具有不同奇偶校验值的最小跳转,包括了程序查找在Python中达到具有不同奇偶校验值的最小跳转的使用技巧和注意事项,需要的朋友参考一下 假设,我们获得了一个称为nums的数字列表。如果列表中存在值,则可以从索引i跳转到索引i +数字[i]或从索引i跳转到i −数字[i]。因此,我们必须找到至少要达到另一个具有不同奇偶校验值的跳跃数,以保持输入顺序不变。如果我

  • 我有一个布尔方法的麻烦,我想检查数组是偶数,奇数,还是两者都不是。我输入数组大小和数组值,但是“isArrayEven”方法仍然输出“array中的所有数字都是偶数”,即使我的数组是1、2、3并且isArrayEven假定是false。 我