给定无序自然数数组,求最大连续自然数个数,时间复杂度为O(n)

来源:互联网 发布:淘宝2016好评返现新规 编辑:程序博客网 时间:2024/05/17 03:22

方法1:排序,然后遍历,复杂度n lg n。

方法2:并查集。用一个hash table记录数据是否出现,一个数组用于实现并查集。每次加入数据x,check 一下哈希table中x-1和x+1是否合法并存在,若存在则合并。最后遍历并查集数组,输出最大的等价类中元素的个数即可。

方法3:类似2,用多个hash table:

维持两个hash表tables: 
Start表,其中的条目都是如下格式(start-point,length),包含的某个连续序列起始数以及序列长度。 
End表,其中的条目都是如下格式(end-point,length),包含的某个连续序列结束数以及序列长度。  

扫描原始数组,做如下操作: 对于当前值value, 
判断value + 1是否存在于start表中。 
如果存在,删除相应的条目,创建一个新条目(value,length + 1),同时更新end表相应条目,结束数不变,该对应长度加一。
判断value - 1是否存在于end表中。 如果存在,删除相应的条目,创建一个新条目(value,length + 1),同时更新start表相应条目,开始数不表,该对应长度加一。 如果在两个表中都存在,则合并两个已经存在的连续序列为一个。将四个条目删除,新建两个条目,每两个条目代表一个连续序列。 如果都不存在,则只需要在两个表中创建一个新的长度为1的条目。 一直这样等到数组中所有元素处理完毕,然后扫描start表寻找length值最大的那个即可。 这里要达到O(n)时间复杂度,start表和end表都用hash表实现,而且必须满足相关操作查找/添加/删除能够在O(1)时间复杂度内完成。

实例分析: 
int[] input = {10,21,45,22,7,2,67,19,13,45,12, 11,18,16,17,100,201,20,101};  
初始化状态:
Start table:{}
End table:{} 
开始遍历数组: 
10:两个数组中都不存在,添加条目。 
Start table:{(10,1)} 
End table:{(10,1)} 
21:两个数组中都不存在,添加条目。 
Start table:{(10,1),(21,1)} 
End table:{(10,1),(21,1)} 
45:两个数组中都不存在,添加条目。 
Start table:{(10,1),(21,1),(45,1)} 
End table:{(10,1),(21,1),(45,1)} 
22:22-1=21存在于end表中需要进行更新。 
Start table:{(10,1),(21,2),(45,1)} 
End table:{(10,1),(22,2),(45,1)} 
7:两个数组中都不存在,添加条目。 
Start table:{(10,1),(21,2),(45,1),(7,1)} 
End table:{(10,1),(22,2),(45,1),(7,1)} 
2:两个数组中都不存在,添加条目。 
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1)} 
End table:{(10,1),(22,2),(45,1),(7,1),(2,1)} 
67:两个数组中都不存在,添加条目。 
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1),(67,1)} 
End table:{(10,1),(22,2),(45,1),(7,1),(2,1),(67,1)} 
19:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1),(67,1),(19,1)} 
End table:{(10,1),(22,2),(45,1),(7,1),(2,1),(67,1),(19,1)} 
13:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)} 
End table:{(10,1),(22,2),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)} 
45:两个数组中都不存在,添加条目。 
Start table:{(10,1),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)} 
End table:{(10,1),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)} 
12:12+1=13存在start表中,更新。 
Start table:{(10,1),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(12,2)} 
End table:{(10,1),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(13,2)} 
11:11+1=12都存在,合并。 
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1)} 
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1)} 
18:18+1=19存在start表中,更新。 
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(18,2)} 
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,2)} 
16:都不存在,添加条目。 
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(18,2),(16,1)} 
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,2),(16,1)} 
17:都存在,合并。 
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(16,4)} 
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,4)} 
100:都不存在,添加条目。 
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(16,4),(100,1)} 
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,4),(100,1)} 
201:都不存在,添加条目。 
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(16,4),(100,1),(201,1)} 
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,4),(100,1),(201,1)} 
20:都存在,合并。 
Start table:{(10,4),(16,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1)} 
End table:{(13,4),(22,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1)} 
101:都存在,合并。 
Start table:{(10,4),(16,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1),(101,1)} 
End table:{(13,4),(22,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1),(201,1)}  
最后搜索start表,找到length值最大的,为7.连续自然数序列是:(16,17,18,19,20,21,22). 结束。


原创粉丝点击