最长连续序列
给定一个未排序的整数数组,找出最长连续序列的长度。
说明
要求你的算法复杂度为O(n)
样例
给出数组[100, 4, 200, 1, 3, 2],这个最长的连续序列是 [1, 2, 3, 4],返回所求长度 4
由于复杂度为o(N), 我们用hashmap来记录每个数所在的最长子序列长度。
刚开始遍历数组时,比如遍历到3这个数,若3已经在map中了,跳过,表明已经处理过了;若3不在map中,先加入到map里,value为1,表示3目前所在的最长连续序列长度为1;
接着就要考虑3的前后两个数是否在map中,若存在,则3的value需要更新;
用一个merge()方法去计算合并完之后的序列长度。
比如,对3来说,2存在于map中,他的序列长度为a。那么可以求得,2所在序列的起始长度为2-a+1. 注意,只有序列的首末元素才能如此计算,也就是我们要确保计算的元素一定是首末元素。再令4所在序列的长度为b,则该序列末尾元素为4+b-1.
至此,我们求得了一个连续序列:[2-a+1, 4+b-1]
对于这样一个序列,只有他的首末元素暴露在计算中,故只更新首末元素在map中的value值即可。
因为对于任意一个元素,我们只看他能否连接两个子序列,或者他能否跟在某序列屁股后面形成新序列。
public int longestConsecutive(int[] num) { if(num == null || num.length == 0) return 0; int max = 1; Map<Integer, Integer> map = new HashMap<>(); for(int i = 0; i < num.length; i++){ if(!map.containsKey(num[i])){ map.put(num[i], 1); if(map.containsKey(num[i] - 1)){ max = Math.max(max, merge(map, num[i]- 1, num[i])); } if(map.containsKey(num[i] + 1)){ max = Math.max(max, merge(map, num[i], num[i] + 1)); } } } return max; } public int merge(Map<Integer, Integer> map, int less, int more){ int left = less - map.get(less) + 1; int right = more + map.get(more) - 1; int len = right - left + 1; map.put(left, len); map.put(right, len); return len; }