algorithm - 在 O(n) 中找到 j 和 i 索引之间的最大差异,使得 j > i 和 a[j] > a[i]

标签 algorithm sorting data-structures

给定一个未排序的数组,找到索引之间的 max j - i 差异使得 j > ia[j ] > a[i]O(n) 中。我能够在 O(n^2) 复杂性中使用简单的方法找到 ji 但想知道如何在O(n)

Input: {9, 2, 3, 4, 5, 6, 7, 8, 18, 0}

Output: 8 ( j = 8, i = 0)

Input: {1, 2, 3, 4, 5, 6}

Output: 5 (j = 5, i = 0)

最佳答案

为了简洁起见,我假设所有元素都是唯一的。该算法可以扩展以处理非唯一元素的情况。

首先,观察如果xy分别是你想要的最大和最小位置,那么就不能有任何 a[i] > a[x]i > x ,同样,没有 a[j] < a[y]j < y .

所以我们沿着数组a扫描并构建一个数组 S这样 S[i]保存 a[0:i] 中最小元素的索引.同样是一个数组 T其中包含 a[n-1:i] 中最大元素的索引(即向后)。

现在我们可以看到 a[S[i]]a[T[i]]必然是递减序列,因为它们是 i 之前的最小值最大值来自 n直到 i分别。

所以现在我们尝试执行类似合并排序的过程。在每一步,如果 a[S[head]] < a[T[head]] ,我们从 T 中弹出一个元素, 否则我们从 S 弹出一个元素.在每个这样的步骤中,如果 a[S[head]] < a[T[head]],我们会在 S 和 T 的头部记录差异。 .最大的差异会给您答案。

编辑:这是一个用 Python 实现算法的简单代码。

def getMaxDist(arr):

    # get minima going forward
    minimum = float("inf")
    minima = collections.deque()
    for i in range(len(arr)):
        if arr[i] < minimum:
            minimum = arr[i]
            minima.append((arr[i], i))

    # get maxima going back
    maximum = float("-inf")
    maxima = collections.deque()
    for i in range(len(arr)-1,0,-1):
        if arr[i] > maximum:
            maximum = arr[i]
            maxima.appendleft((arr[i], i))

    # do merge between maxima and minima
    maxdist = 0
    while len(maxima) and len(minima):
        if maxima[0][0] > minima[0][0]:
            if maxima[0][1] - minima[0][1] > maxdist:
                maxdist = maxima[0][1] - minima[0][1]
            maxima.popleft()
        else:
            minima.popleft()

    return maxdist

关于algorithm - 在 O(n) 中找到 j 和 i 索引之间的最大差异,使得 j > i 和 a[j] > a[i],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18281625/

相关文章:

algorithm - 在什么情况下我应该使用尝试而不是二叉树/哈希表?

用于外部排序的 C# N 方式合并

java - 冒泡排序没有排序

java - 有没有类似于队列的数据结构,可以对不同的线程进行多播?

arrays - 查找最多具有 k 个奇数元素的不同连续子数组的数量

java - 如何为我的数组创建 insertInOrder 方法

algorithm - 请建议一个开放数据的图表

algorithm - 这个算法的复杂度是多少?

java解密算法给出java.lang.ArrayIndexOutOfBoundsException : -59

java - 对子列表进行排序,Java