【问题标题】:maximum i-j , so that A[i]>=A[j]最大 i-j ,因此 A[i]>=A[j]
【发布时间】:2017-09-10 02:45:33
【问题描述】:

假设我们有一个正整数数组 A。我们的任务是找到最大可能的 i-j , i>j 具有以下性质:A[i]>=A[j]。

举个例子,如果

A[0]=78
A[1]=88
A[2]=64
A[3]=94
A[4]=17
A[5]=91
A[6]=57
A[7]=69
A[8]=38
A[9]=62
A[10]=13
A[11]=17
A[12]=35
A[13]=15
A[14]=20
A[15]=15

那么答案是 10 ,因为对于 i=14 和 j=4 , A[i]>A[j] 。

哪种算法最适合该任务?

到目前为止,我已经考虑了以下算法: 我申请 mergesort 。我使用变量 max 来存储最终答案。每当 A[i] 和 A[j] 没有交换时,我都会检查 i-j> max 。如果是这样,我会更新最大值。 时间复杂度:O(nlogn)。

有更好的算法吗?

【问题讨论】:

  • 更好是什么意思?这是否意味着在时间或空间复杂度方面更快?这是否意味着更易于实现的算法?
  • 既然 A[i] (91) >= A[j] (17) 并且 i > j,为什么答案 i=5 (91) 和 j=4 (17) 不是? .您是否需要索引或值方面的最大可能 i-j?
  • 如果我们选择 i=5 和 j=4 ,那么 A[i] > A[j] 是真的。但是,我们将有 5-4=1 作为答案。如果我们选择 i=14 和 j=4 ,那么 A[i] > A[j] 也是正确的。在这种情况下,我们有 14-4=10 。我们需要找到最大的 i-j ,所以我们选择 i=14 和 j=4 ,答案是 10。
  • @user3697730 我不确定你的算法是正确的还是真的是 O(nlogn)。 ` 每当 A[i] 和 A[j] 没有交换时 ` 是什么意思?
  • @user3697730:这行不通。即使您保留有关元素原始位置的信息(以便实际计算 i-j 值),您也可能永远不会同时查看需要查看的 i 和 j。

标签: arrays algorithm int


【解决方案1】:

对于长度为 N 的数组,我们可以在 O(N) 中完成此操作。

对于ij 给我们最大的i-j,我们必须使A[i] 大于所有后续元素,A[j] 小于所有先前元素。否则,我们可以选择更晚的A[i],或更早的A[j],并获得更大的i-j

查找A 的所有元素大于所有后续元素,以及A 的所有元素小于所有先前元素:

j_candidates = [0]
for j in range(1, N):
    if A[j] < A[j_candidates[-1]]:
        j_candidates.append(j)

i_candidates = [N-1]
for i in reversed(range(N-1)):
    if A[i] > A[i_candidates[-1]]:
        i_candidates.append(i)
i_candidates.reverse()

然后对于每个j 候选者,找到最佳对应的i 候选者,从前一个j 候选者的最佳i 候选者开始搜索

best_distance = 0
i_candidate_index = 0
for j in j_candidates:
    while (i_candidate_index + 1 < len(i_candidates)
           and A[j] <= A[i_candidates[i_candidate_index+1]]):
        i_candidate_index += 1
    best_distance = max(best_distance, i_candidates[i_candidate_index] - j)

【讨论】:

  • 这个 O(n) 怎么样?第二部分是 O(n^2),不是吗?我错过了什么?
  • @Caner:第二部分是 O(N)。内部循环不会每次都遍历整个i_candidates 列表;在整个外循环过程中,内循环仅执行 O(len(i_candidates)+len(j_candidates)) 次迭代。
  • 是的,也就是 O(n),这使得这个算法 O(n^2)
  • @Caner:它在外循环的整个执行过程中执行 O(n) 次迭代,而不是在外循环的每次迭代中执行 O(n) 次迭代。跨度>
  • 考虑这种情况:A[0]=N, A[1]=N-1,A[2]=N-2。 i_candidate 和 j_candidate 数组都有 N 个成员。
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 2019-04-19
  • 2013-08-19
  • 2012-10-20
  • 2021-09-04
相关资源
最近更新 更多