Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2]
,
The longest consecutive elements sequence is [1, 2, 3, 4]
. Return its length: 4
.
Your algorithm should run in O(n) complexity.
首先先不管O(n)的限制想几个方案。
第一思路,比较偷懒。
1. 从小到大排序,然后找最长的公差为1的等差数列。
当然,时间复杂度是O(nlogn)。这里我的一种理解是:使用O(nlogn)的计算量,计算出了超过题目要求的信息量,多余的信息量并没有被使用。
第二思路,
1. 要减小信息量,就得从题目中挖掘出更多的信息。(高中做题目的时候总结的,要充分挖掘题目里边每一个字、词以及句子所包含和隐含的信息)
连续的序列有一个特征是:对于一个m长的连续数字,数字之间的差小于m-1,所以我就想可不可以使用这个信息,来对数字进行逐个分类。
将第一个数字作为一个类,对剩下的数字,使用这种方法进行分类,如果某个数字与某一类的差小于x(x最开始时是m,随着运行会相应变化),慢慢将数字分类。
这个思路,第一遍遍历之后,能保证,连续的数字在一个类中,但是可能在这个类中混入其他的数字。可能需要再次对每一类进行再分类。
这里不知道分到什么时候是个头。。。所以这个思路先停在这里吧~
第三思路:
1. 对数组中的每一个数字m,找它的前驱m-1和m+1有没有在数组中,并在遍历的过程中记录这种联系。
缺点:平常来讲,一个数字有没有在某个数组中需要O(n)的复杂度,乘起来就是 n^2了。
分析:对于每个元素肯定是要遍历一边的,要不然信息是不完备的。
所以思考能不能加速这里边的第二部,查找某个数字在不在数组中。找某个数,最快的方法是?hash。 O(1)。先建立每个数的值为key的hash,然后遍历数组,并找出需要记录的联系。然后再遍历这种联系,找出最大的连续数组。
Intuition: 总感觉使用hash就像开挂一样~~因为虽然从分析上来说从hash表中找元素的时间复杂度是O(1),hash的基本原理大家也都懂,但是实际操作起来hash非常的灵活:hash函数的好坏以及效率,以及内存的开销划算不划算,都是值得考虑而且非常灵活的问题。
思路三解决这个问题,代码还没写,有空了写。