【问题标题】:Get the Sum of all positive numbers in a Circularly ordered array in O(Log N)在 O(Log N) 中获取循环排序数组中所有正数的总和
【发布时间】:2019-10-03 20:33:23
【问题描述】:

我在课堂上得到了一个需要以下内容的练习:

一个由 N 个整数组成的数组 v 是循环排序的,如果,要么数组是有序的,要么是 v[N‐1] ≤ v[0]∃k0<k<N,例如 ∀i≠k v[i] ≤ v[i+1]

例子:

给定一个包含多达 10 个正数项的循环排序数组,计算正数的总和。对于最后一个示例,答案是 27。

我被要求在 java 中使用 分而治之 方案来实现它,因为复杂性在最坏的情况下是 O(Log N) , 为 N 数组大小。

到目前为止,我尝试旋转一个值,直到找到一个正值,然后知道其他正值是相邻的,可以将 10 个正值的最大值相加,复杂度为 O(1)。

我曾想过进行二分搜索以实现 O(Log N) 复杂度,但这不会遵循分而治之的模式。

我可以通过这样的 O(N) 复杂度轻松实现它:

public static int addPositives(int[] vector){

    return addPositives(vector,0,vector.length-1
}

public static int addPositives(int[] vector, int i0, int iN){
    int k = (i0+iN)/2;
    if (iN-i0 > 1){
        return addPositives(vector,i0,k) + addPositives(vector,k+1,iN);
    }else{
        int temp = 0;
        for (int i = i0; i <= iN; i++) {
            if (vector[i]>0) temp+=vector[i];
        }
        return temp;
    }
}

但是尝试降落 O(Log N) 让我无处可去,我该如何实现呢?

【问题讨论】:

  • 所有正数的数组是有效输入吗?
  • 是的,但是有10个正数的限制,你可以有一个100个数字长的数组,但只有10个可以是正数。
  • 按照 Eran 的建议,这里有一个使用分而治之技术的加法解决方案。该解决方案不过滤元素。这是您必须做的额外步骤。

标签: java arrays optimization


【解决方案1】:

如果您修剪不相关的递归分支,您可以改进分而治之的实现以满足所需的运行时间。

将当前数组分成两个子数组后,比较每个子数组的第一个和最后一个元素。如果两者都是负数并且第一个小于最后一个,那么您肯定知道该子数组中的所有元素都是负数,并且您不必对其进行递归调用(因为您知道它将贡献 0总和)。

如果子数组中的所有元素都是正数,您也可以停止递归(也可以通过比较子数组的第一个和最后一个元素来验证) - 在这种情况下,您必须对所有元素求和子数组,所以没有必要继续递归。

【讨论】:

    【解决方案2】:

    我对 O(Log N) 的建议是直接比较以满足两个标准中的第二个:最后一项小于第一个。 return vector[0] &gt;= vector[iN-1]

    如果你想要更复杂的东西,我忘记了算法名称,但你可以在中点获取数组,然后从那里进行两次有序搜索:从中间到开始,然后从中间到结束

    【讨论】:

      猜你喜欢
      • 2023-01-16
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      相关资源
      最近更新 更多