查找给定约束的最大指数差

时间:2018-09-25 17:33:08

标签: python algorithm

在寻求学习算法设计的过程中,我开始练习问题,而这些特殊问题使我难以找到有效的解决方案。

  

给定一个整数数组A,求j的最大值-i服从   A [i] <= A [j]的约束。 A:[3 5 4 2]输出:2对   (3,4)

def maxIndex(arr):
  max_val = float("-inf")
  for i in range(0,len(arr)):
    for j in range(i + 1 , len(arr)):
      #print(arr[i],arr[j])
      if arr[i] <= arr[j]:
        diff_i = j - i
        if diff_i > max_val:
          max_val = diff_i
  return max_val

A  = [3, 5, 4, 2]
print("Result :",maxIndex(A))

我上面的幼稚方法可以工作,但时间复杂度为O(n ^ 2),空间复杂度为O(1)。

这里的值和索引都很重要。如果我将列表排序不正确并将索引存储在字典中,我仍然必须使用嵌套的for循环来检查j - 1约束。 / p>

如何改善时间复杂度?

5 个答案:

答案 0 :(得分:0)

您可以创建两个辅助数组,以便最小数组在索引i处存储最小值,直到索引i,类似地,最大数组包含直到索引i的最大数组值(反向遍历) 您可以在这里https://www.geeksforgeeks.org/given-an-array-arr-find-the-maximum-j-i-such-that-arrj-arri/

找到答案

答案 1 :(得分:0)

对于给定的问题,我可能会想到一个可能的解决方案,就是从给定的列表创建一个成对的列表,该列表保留列表索引以及列表值,即(A的列表 i ,i)列表中的所有元素。

您可以按升序对给定的成对列表进行排序,并从左到右进行迭代。我们维护一个变量,该变量表示到目前为止在迭代min_index中遇到的最小索引。现在,在每个步骤 i 中,我们将答案更新为 ans = max(ans,index i -min_index)iff index i > min_index 以及我们的min_index以及我们的min_index min_index = min(index i ,min_index)由于我们的列表已排序,因此可以确保 A [i]> = A [min_index]

由于我们需要首先对数组进行排序,所以该解决方案的总体复杂度为O(nlog(n))

答案 2 :(得分:0)

如上所述,is an O(n) solution是最有效的。我将在O(n log n)中添加另一种解决方法:

我们可以考虑这个问题,因为对于每个索引i,知道最远的索引j> i,其中a [i] <= a [j]。如果有了这个,我们只需要评估索引的差异并在其上保持最大值。那么,如何计算这些信息?

  1. 将所有元素以对(元素,索引)的形式添加到集合中,以便它首先按元素排序,然后按索引排序。
  2. 现在从最后一个元素开始向后迭代数组。对于元素中小于或等于当前元素的集合中的每一对,我们将其最远的索引设置为当前索引,然后将其从集合中删除。
  3. 完成所有步骤后,评估每个i的最远索引j,答案是那些i的最大值

请注意,对于每个元素,我们需要在集合中搜索所有较低的值。搜索是O(log n),虽然我们可以进行更多的迭代,但是当我们稍后从集合中删除它时,我们只对每个元素进行了一次迭代,因此总体复杂度为O(n log n)。

答案 3 :(得分:0)

有一种方法使用O(nlogn)时间(虽然我感觉应该存在线性算法)。

列出min-candidates

遍历源列表。

如果当前项目小于当前最小值,则将其索引添加到min-candidates。因此,相应的值将按降序排序。

如果当前项目大于当前最小值,请使用二进制搜索在min-candidates中搜索第一少的项目。找到索引差异并与当前最佳结果进行比较。

答案 4 :(得分:0)

这可以在O(nlogn)时间和O(n)空间中解决。

  1. 创建[值,索引]的元组列表
  2. 按值对它们进行排序
  3. 将min_index初始化为某个最大值(list.length +1)
  4. 初始化索引差的最大值
  5. 初始化一个元组以捕获具有最大差异的索引。
  6. 现在执行以下步骤(伪代码):

min_index = list.length + 1 max = 0 max_tuple = [] for tuple t in list: min_index = minimum( t.index, min_index ) if ( t.index != min_index ) if ( t.index - min_index >= max ) max = t.index - min_index max_tuple = [min_index, t.index]

换句话说,您跟踪最小索引,并且由于列表已排序,因此当您按递增值顺序浏览列表时,您将在最小索引和当前索引之间得到一个需要最大化的差异。