【问题标题】:Is there any good algorithm implementation that can find nearest negative elements from specific array elements?有没有什么好的算法实现可以从特定的数组元素中找到最近的负元素?
【发布时间】:2020-09-25 09:22:09
【问题描述】:

我目前正在做C编程,当当前索引定义为int变量idx时,我需要从idx中找到[0, idx-1]范围内最近的负元素数组。

例如,如果数组是 1 -2 3 -4 5 6 并且 idx 是 5(array[idx] 将是 6),函数必须返回 3,因为 -4 是 array[idx] 中最近的负元素。

我知道如何线性解决这个问题,比如

for(int i = idx-1; i>=0; i--){
   if(array[i] < 0) return i;
}

但我想知道更快的算法(这意味着具有较低时间复杂度的算法),因为我目前正在研究元素超过百万的大型数组。有人可以帮忙吗?

【问题讨论】:

  • O(N) 是最好的情况,但如果数组没有改变,你可以缓存结果。一次搜索包含一百万个元素的数组还不错。
  • 我必须在迭代数组时执行这个函数(idx是数组的迭代器),所以整体复杂度应该是O(n^2)。但我想我别无选择:(
  • @Martin Jones "unction 必须返回 3, as -4 " 为什么不是 1 as -2?
  • 在你迭代它时数组会改变吗?如果不是,那么只需记住最后一个负值的索引。

标签: c arrays performance search time-complexity


【解决方案1】:

您可以创建一个位数组一次,为每个包含负数的索引设置一位。如果将此位数组存储为 64 位无符号整数,则可以同时检查 64 个索引。

如果您有 1 亿个条目,并且只有万分之一的条目是负数,您可以创建第二个位数组,为第一个数组中的每个 64 位数字设置一个位。因此,检查该数组中的 one 数组元素允许您同时检查 4096 个条目。

这当然是多一点的代码。当负数很少时,它会更快。

如果您必须在遍历数组时执行此操作,那会更容易。只记得最后的结果。假设您发现最接近索引 500,000 的负数位于索引 493,005。现在您想要最接近索引 500,001 的负数。它可能在哪里?它可能位于索引 500,000 处,如果该数字不是负数,则它再次位于 #493,005。对于所有 i,在 O(n) 中计算是微不足道的,而不是 O(n^2)。

【讨论】:

    【解决方案2】:

    O(N) 是最好的,无需额外信息即可完成。考虑一个不包含负值的数组。唯一确定的方法是访问整个数组。

    【讨论】:

      【解决方案3】:

      如果数组非常大并且负数很少,您可以通过对 8 或 16 个数字的块进行 OR 运算并将结果与​​ 0 进行比较来加快执行速度。正数或零结果意味着这些数字都不是负数,负数结果意味着这些数字至少是一个,您可以通过更简单的循环(无边界条件)找到。

      这种方法产生的测试更少,并且数组元素的 OR-ing 块可以编译为矢量化代码,因此性能应该更好,但复杂度保持不变:线性时间。根据您的数据集,仔细的基准测试将判断这是否值得。

      【讨论】:

        猜你喜欢
        • 2019-09-14
        • 2019-07-07
        • 1970-01-01
        • 2023-03-22
        • 2023-03-30
        • 2014-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多