Longest Consecutive Sequence
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.
思路一:
用HashMap,用空间换取时间。
在Map中用key和value表示一些连续的数字集合,比如有[1,2,3],便将<1,3>和<3,1>都存入Map,这样就可以在O(1)的时间查询到目前是否包含以某个数字开始(letf)或结尾(right)的集合。
从头到尾扫描数组,处理数字num时,先判断是否已经有以num开头或者结尾的集合说明此num是一个重复的元素,忽略之;当Map中存在以num-1结束的集合时(Map.get(num-1)<num)num变为新的right,left保持原样,即置为Map.get(num-1)的值,然后将Map中key为num-1的项移除;同样的方法判断num+1;最后将更新的left,right,即<left,right>和<right,left>,都put进Map中,再用当前集合的长度更新结果。
1 public int longestConsecutive(int[] num) { 2 if(num == null || num.length == 0) { 3 return 0; 4 } 5 HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); 6 int ret = 0; 7 for(int i=0; i< num.length; i++) { 8 Integer left = num[i]; 9 Integer right = num[i]; 10 //去重 11 if(map.containsKey(num[i])) { 12 continue; 13 } 14 Integer board = map.get(num[i]-1);//left board 15 if(board!=null && board<left) { 16 left = board; 17 map.remove(num[i]-1); 18 } 19 board = map.get(num[i]+1);//right board 20 if(board!=null && right<board) { 21 right = board; 22 map.remove(num[i]+1); 23 } 24 //合并后的集合 25 map.put(left, right); 26 map.put(right, left); 27 ret = Math.max(ret, right - left + 1); 28 } 29 return ret; 30 }
思路二:
先把所有数字都放入一个HashSet中。
从头到尾扫描数组,处理数字num时,先把num移除Set,再依次判断num-1,num-2...num+1,num+2...是否在Set中,如果在则将其移除Set并肩本次sum增加1,如果不在则不再向下判断,每次都更新结果为最大的长度。
1 public int longestConsecutiveII(int[] num) { 2 if(num == null || num.length == 0) { 3 return 0; 4 } 5 HashSet<Integer> set = new HashSet<Integer>(); 6 int ret = 0; 7 for(int i : num) { 8 set.add(i); 9 } 10 for(int i : num) { 11 set.remove(i); 12 int sum = 1; 13 int tmp = i-1; 14 while(set.contains(tmp)) { 15 set.remove(tmp);//要在tmp--之前 16 sum++; 17 tmp--; 18 } 19 tmp = i+1; 20 while(set.contains(tmp)) { 21 set.remove(tmp); 22 sum++; 23 tmp++; 24 } 25 ret = Math.max(sum, ret); 26 } 27 return ret; 28 }