问题 搜索未排序数组中元素的最快方法


我今天刚刚提出了这个问题,并且正在尝试一种比O(N)更好的解决方案,但却找不到一个。

通过SO搜索但无法找到这个问题。

有没有比O(n)更好的解决方案,还是一个无法解决的问题呢?

我最初的想法是二进制搜索,但是你需要再次对它进行排序> n。我还考虑过将quicksort应用于搜索元素可能属于的数组的一半,但我们最初还是进行了n次比较,之后才丢弃另一半。我是正确的,还是我在错误的方向上看待解决方案?

我试图用c ++解决方案而没有javascript的IndexOf()或C#Array.find()或LINQ。


4048
2017-10-05 04:45


起源

我认为你不能做得更好 O(n) 如果它没有排序。 - Mysticial
如何从阵列的两端进行搜索,如果元素不存在则在中间进行会议。它可以在固定大小的数组或循环链表上工作。


答案:


让它平行。将数组划分为块并并行搜索。 复杂性将是O(n),但运行时间会少得多。实际上它与否成正比。你有的处理器。

您可以使用 并行模式库 在C ++中


9
2017-10-05 04:50



我打赌它会在你获得任何显着加速之前成为记忆限制。 - Mysticial
@Mysticial在这种情况下,您可以在群集上分发搜索,如果文件足够大,则将文件分成块。 - Muhammad Hasan Khan
是的我还考虑打破数组并尝试使用它们的线程,但这不是这个问题的算法视角。这又是一个特定的实现,如IndexOf()或find() - Ajai
@MuhammadHasanKhan它与将涉及的CPU核心数量不成比例。见Amdal定律 - en.wikipedia.org/wiki/Amdahl%27s_law - DaddyM


你是对的,最快的方法是简单地遍历数组并寻找它。没有进一步的信息,你无能为力。

除非你有 量子计算机, 那是。


3
2017-10-05 04:48



我希望你不会用C ++编程量子计算机 - Foo Bah
如果你要计算并行性,那么是的,你可以做得更好 O(n) 时间。 :) - Mysticial
@Mysticial除非你有多个处理器可比 n (也就是说,无数个处理器),它不会改变渐近时间。 - bdares
有时我想知道是否有人真正关注什么 O 实际意味着。 -_- - ELLIOTTCABLE


如果您要搜索一个元素,只需迭代它。没有办法让它更快。

如果您正在多次搜索,那么将其编入索引(或者如果您愿意将其排序)并快速进行以下搜索(log(n))是值得的。


2
2017-10-05 04:49



是的......你是对的...但是找到一种只做一次的方法可能会很惊人,也可以使用n次而不使用索引数字的二进制搜索。 - Ajai
不可能。并非不可能,因为“你不可能在空中跳3米”,因为这可能发生在许多类固醇和弹性地板上,但不可能,因为1 + 1不能等于3。 - bdares
哈哈...!同意。我刚刚发布了这个问题,以确定我是否是唯一一个被这个打动的人还是更多? :P - Ajai


如果它没有排序,你必须检查每个元素。


1
2017-10-05 04:49





您可以使用此方法使用O(1)搜索元素。

只需创建一个 地图 。当您为该键指定值插入值为'1'时,再次搜索它时,只需检查该数组是否存在。

以下是代码: -

#include<bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin>>n;
    map<int,int> map;
    for(int i=0;i<n;i++){
        int k;
        cin>>k;
        map[k]=1;
    }
    int num;
    cin>>num;

    if(map[num]){
        cout<<"FOUND"<<endl;
    }else{
        cout<<"NOT FOUND"<<endl;
    }

    return 0;
}



Input: 
5    // *no. of elements*
6 4 7 3 2  //*elements* 
3    // *number to find*

输出:FOUND


0
2017-09-07 15:50



这假设您有额外的内存。通常不适合大型阵列。除非搜索次数足够高,否则这通常不是一个好的交易。 - 0xc0de
如果您正在搜索数组中的数字,那么您可以将其应用于。 - Yadvendra Kumar


所有答案都错了!可以使程序比O(n)运行得更快。快多了。 首先使用合并排序算法对数组进行排序,然后使用二进制搜索来查找元素。 algoro的运行时间均为O(log_2(n))。将这两个复杂性加在一起,得到2 * log_2(n),即见证C = 2的O(log_2(n))。


-2
2017-09-15 22:30



合并排序复杂度为O(n * log(n))。在致电之前获取您的事实 所有 错误。如果你需要它的原始顺序,你也不能排序数组,这取决于手头的任务。你觉得分类需要比搜索更多的工作吗?排序只有在没有时才有意义。搜索量很高(超过某个阈值)。 - 0xc0de
是的,我忘记了合并功能。但二进制搜索的运行时间仍为O(log_2(n))。将此添加到合并排序的运行时间,您得到nlog_2(n)+ log_2(n),等于O(nlog_2(n))与目击者C = 2和n_0 = 0,这是非常好的。 - Martin Pekár
那么,O(n * log(n))比线性搜索的O(n)差。 - 0xc0de