Java 在无hashmap的未排序数组中查找最长的连续整数序列
使用Java,我必须创建一个程序,该程序接受一组有序的数字,并返回最长连续数字序列的长度。例如,对于集合(1,18,12,6,8,7,13,2,3,4,9,10),该方法应返回5,因为最长的连续序列是(6,7,8,9,10)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的算法,您可以使用基数排序
它应该尽可能的高效,你不能使用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;
}