【问题标题】:How to find the maximum span of a given array of numbers?如何找到给定数字数组的最大跨度?
【发布时间】:2013-10-10 23:39:05
【问题描述】:

我要解决的问题如下:我想在给定数组中找到最大数字跨度,给定一个由正整数和负整数组成的数组 A 返回最大的 (A[j] - A [i]) 使得 1

  1. 找到数组的第n阶统计量的索引,让它为“i”
  2. 找到数组的一阶统计量的索引,让它为“j”
  3. 如果 i > j,则返回差值,因为我们找到了数组的最大和最小元素之间的差值,因此终止返回差值。
  4. 如果 j > i 然后将数组分成两半,并通过调用此函数找到两半中的最大跨度,即 A[1....i] 和 A[i + 1 ......n]递归算法,当算法找到这样的一对 i,j 时,它会返回这些对之间的差异,否则它会继续递归并最终终止。
  5. 返回最大值{子数组 1 的最大跨度,子数组 2 的最大跨度}

这个算法是 O(nlogn) 但我不知道它是否正确。

【问题讨论】:

  • 那么如果你计算“span”,你只想计算那个数组中最大和最小数之间的差异?
  • 啊我大概明白了,所以是 Max 和 Min,但 Min 必须始终在“左侧”
  • 是的,最小值必须始终在左边 A[j] - A[i] 1
  • 我认为你的算法是错误的 {9,-5,-4,6,7,8} 呢?

标签: algorithm recursion recurrence


【解决方案1】:

@mrip 解决方案的时间复杂度为 O(n),空间复杂度为 O(n)。这是正确的,但是对于这个问题只有 O(1) 的空间复杂度就足够了。

int min=a[0],ans=0;
for (int i=1;i<n;i++)
    if (a[i]<min) min=a[i];
    else ans=max(ans,a[i]-min);
return ans;

【讨论】:

    【解决方案2】:

    这是一个 O(n) 算法。

    1. 构建一个数组 Max,其中 Max[i] 是 k>=i 时 A[k] 的最大值。这可以通过向后迭代 A 在 O(n) 时间内完成。
    2. 构建一个数组 Min,其中 Min[i] 是 k
    3. 遍历 Max 和 Min 以找到最大化 Max[i]-Min[i] 的索引 i。也是 O(n)。
    4. 返回 (Min[i],Max[i])。

    编辑时:有一个极端情况,数组是反向排序的,在这种情况下,所有 i 的 Max[i]=Min[i]=A[i]。这可以在 O(n) 时间内检测到,在这种情况下,您只需返回最大化 A[i+1]-A[i] 的一对相邻元素(这将是负数)。

    【讨论】:

    • 我相信这是正确的(但我并不肯定)。但是,它不是 O(nlogn)。在最坏的情况下,它是 n^2。如果 i 总是靠近数组的中间,它将是 O(nlogn),但不能保证这一点,而且与快速排序不同,没有(明显的)随机化方法。
    • 你确定步骤 3. if O(n)?
    • @libik 非常确定。您只需要迭代一次。为什么你认为需要更长的时间?
    • mrip :是的,是的,现在我看到了……你真是个天才:D
    猜你喜欢
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 2011-10-27
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    相关资源
    最近更新 更多