Java 在无hashmap的未排序数组中查找最长的连续整数序列

Java 在无hashmap的未排序数组中查找最长的连续整数序列,java,algorithm,methods,performance,Java,Algorithm,Methods,Performance,使用Java,我必须创建一个程序,该程序接受一组有序的数字,并返回最长连续数字序列的长度。例如,对于集合(1,18,12,6,8,7,13,2,3,4,9,10),该方法应返回5,因为最长的连续序列是(6,7,8,9,10) 它应该尽可能的高效,你不能使用hashmaps,实际上对于迭代来说,我猜最好的选择是对数组进行排序(nlogn),然后再次遍历数组(n)将是最好的选择?如果你有一个如此大的输入以至于O(n log n)算法会太慢,如果您想要一个不使用hashmap的算法,您可以使用基数排序

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


它应该尽可能的高效,你不能使用hashmaps,实际上对于迭代来说,我猜最好的选择是对数组进行排序(nlogn),然后再次遍历数组(n)将是最好的选择?

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

基数排序:

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

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

static final int RADIX_POW2=4//如果需要,也可以使用8
//两倍的速度和16倍的空间占用率。
静态最终整数基数=1移位和(基数-1)]。添加(x);
整数计数=0;
用于(ArrayList存储桶:存储桶){
用于(整数x:桶)
输入[count++]=x;
bucket.clear();
}
}
静态无效基数\排序\满(int[]输入){
ArrayList[]bucket=新的ArrayList[基数];

对于(int i=0;我不认为数组排序与目标冲突?6,7,8,9,10在给定数组中不按该顺序出现。这没关系吗?通过跟踪当前最长的大小,然后快速检查排序后的数组是否可能是正确的值,可以获得一定的加速(也就是说,如果最长的序列是5,而我当前在
I
处的数字是1,那么如果
I+5
不是
6
,我可以直接跳到
I+5
@aliternal请注意,如果您可以在(n)中执行此操作,则不需要这样做。)没有排序的情况下运行时间或更好,我发现的所有示例都使用哈希映射,所以我想这是不可能的?@DonRoby我想排序后它会出现在
中,否则你完全正确。基数排序不是O(n),而是O(d·n)对于数字为d或更少的n个键。虽然在处理Java基元整数类型时d可能被视为常量,但您可能至少应该注意这一点。@Dukeling谢谢,我应该提到这一点。
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;
}