在没有散列映射的未排序数组中找到最长的连续整数序列

时间:2014-03-17 01:17:36

标签: java algorithm methods performance

使用Java,我必须创建一个程序,它接受一组有序的数字并返回最长的连续数字序列的长度。例如,对于集合(1,18,12,6,8,7,13,2,3,4,9,10),该方法应返回5,因为最长的连续序列是(6,7,8,9) ,10)。

它应该尽可能高效,你不能使用散列图,实际上只是迭代我猜测最好的选择是对数组进行排序(nlogn),然后再次运行数组( n)将是最好的选择吗?

1 个答案:

答案 0 :(得分:1)

如果您有如此大的输入以致O(n log n)算法太慢并且您想要一个不使用hashmap的算法,则可以使用基数排序并仍然获得相同的O(n)性能。

基数排序:http://en.wikipedia.org/wiki/Radix_sort

基本上它通过在最低k(我通常使用4或8)位,然后在下一个最低k位上应用桶排序来对输入进行排序,依此类推,直到所有位都被排序为止。

代码如下所示(对不起,我不熟悉Java,所以它可能包含一些错误,但我希望你能理解我的意思。)

static final int RADIX_POW2=4;//you could also use 8 if you want it 
                              //twice as fast and 16 times as space taking.
static final int RADIX=1<<RADIX_POW2;

static void radix_sort_part(int[] input, ArrayList<int>[] buckets, int shift){
    for(int x:input) buckets[x>>shift & (RADIX-1)].add(x);
    int count=0;
    for(ArrayList<int> bucket:buckets){
        for(int x:bucket)
            input[count++]=x;
        bucket.clear();
    }
}
static void radix_sort_full(int[] input){
    ArrayList<int>[] buckets=new ArrayList<int>[RADIX];
    for(int i=0;i<RADIX;i++)
        buckets[i]=new ArrayList<int>();
    //I'm performing radix sorts on full 32 bits, but if the range of 
    //your inputs are smaller, you only need to perform it on the range.
    for(int i=0;i<sizeof(int)*8/RADIX_POW2;i++)
        radix_sort_part(input,buckets,i*RADIX_POW2);       
}
static int find_max_consecutive(int[] input){
    radix_sort_full(input);
    int maxconsecutive=1;
    int currentconsecutive=1;
    for(int i=1; i<input.size();i++){
        if(input[i]=input[i-1]+1)currentconsecutive++; 
        if(currentconsecutive>maxconsecutive)maxconsecutive=currentconsecutive;
    }
    return maxconsecutive;
}

但是,如果您有许多相对较小的输入并且需要一次又一次地解决此问题,我认为此算法很慢。 对于大量输入,此算法可能与hashmap一样耗费内存,而不是那么快。因此,如果我被要求选择,我宁愿使用hashmap。

修改 我忘了提到基数排序花费的时间与执行桶排序的次数成正比,即((整数的位数)/ RADIX_POW2)。 因此,该算法的确切时间复杂度为O(dn),其中d为(整数的位数)/ RADIX_POW2。 这意味着如果你想将算法用于长数,它需要两倍的时间,如果你想将它用于BigInteger或String或类似的东西,那么整数(字符串)的大小就会花费。