|
1 | 1 | public class Solution { |
2 | 2 | public int longestConsecutive(int[] num) { |
3 | | - // Note: The Solution object is instantiated only once and is reused by each test case. |
4 | | - // we may use hashmap for this purpose |
5 | | - // 1st hashmap (start) maps the start of the consecutive sequence to its length |
6 | | - // 2nd hashmap (end) maps the end of the consecutive sequence to its length |
7 | | - // we scan the array, for each element, we search for num-1 and num+1 in hashmap end and start accoringly |
8 | | - // if it is found, we update the hashmap and check whether any entry of two hashmap can't merged |
9 | | - // for complexity, each element of the array, will at most add one new entry to each hashmap |
10 | | - // i.e., hashmap has space complexity O(n) and hashmap operation take O(1) time |
11 | | - // when we looking for the maximal value for value set of hashmap, the time complexity will be O(n) |
| 3 | + // IMPORTANT: Please reset any member data you declared, as |
| 4 | + // the same Solution instance will be reused for each test case. |
| 5 | + // we have two hashmap to stores the start/end (as key) and the length (as value) of the sequence |
12 | 6 | if (num==null || num.length<1) |
13 | 7 | { |
14 | 8 | return 0; |
15 | 9 | } |
| 10 | + HashSet<Integer> visited=new HashSet<Integer>(); |
16 | 11 | HashMap<Integer, Integer> start=new HashMap<Integer, Integer>(); |
17 | 12 | HashMap<Integer, Integer> end=new HashMap<Integer, Integer>(); |
18 | 13 | for (int i=0; i<num.length; i++) |
19 | 14 | { |
20 | | - boolean flag_start=false; |
21 | | - boolean flag_end=false; |
22 | | - // looking for the consecutive sequence |
23 | | - if(start.containsKey(num[i]+1)) |
| 15 | + int key=num[i]; |
| 16 | + if (visited.contains(key)) |
24 | 17 | { |
25 | | - start.put(num[i], start.get(num[i]+1)+1); |
26 | | - flag_start=true; |
| 18 | + continue; |
27 | 19 | } |
28 | | - else |
| 20 | + visited.add(key); |
| 21 | + if (!start.containsKey(key)) |
29 | 22 | { |
30 | | - start.put(num[i], 1); |
| 23 | + start.put(key, 1); |
31 | 24 | } |
32 | | - if(end.containsKey(num[i]-1)) |
| 25 | + if (!end.containsKey(key)) |
33 | 26 | { |
34 | | - end.put(num[i], end.get(num[i]-1)+1); |
35 | | - flag_end=true; |
| 27 | + end.put(key, 1); |
36 | 28 | } |
37 | | - else |
| 29 | + |
| 30 | + // search to the right, sequence starts with key+1 |
| 31 | + if(start.containsKey(key+1)) |
38 | 32 | { |
39 | | - end.put(num[i], 1); |
| 33 | + start.put(key, start.get(key+1)+1); |
| 34 | + start.remove(key+1); |
| 35 | + } |
| 36 | + |
| 37 | + // search to the left, i.e., sequence ends with key-1 |
| 38 | + if(end.containsKey(key-1)) |
| 39 | + { |
| 40 | + end.put(key, end.get(key-1)+1); |
| 41 | + end.remove(key-1); |
| 42 | + } |
| 43 | + |
| 44 | + // check whether two entry can be merged |
| 45 | + if (start.get(key)>1 || end.get(key)>1) |
| 46 | + { |
| 47 | + int value=start.get(key); |
| 48 | + if (key!=key-end.get(key)+1) |
| 49 | + { |
| 50 | + start.put(key-end.get(key)+1, start.get(key)+end.get(key)-1); |
| 51 | + start.remove(key); |
| 52 | + } |
| 53 | + if (key!=key+value-1) |
| 54 | + { |
| 55 | + end.put(key+value-1, value+end.get(key)-1); |
| 56 | + end.remove(key); |
| 57 | + } |
40 | 58 | } |
41 | | - // looking for a merge |
42 | | - start.put(num[i]-end.get(num[i])+1, start.get(num[i])+end.get(num[i])-1); |
43 | | - end.put(num[i]+start.get(num[i])-1, start.get(num[i])+end.get(num[i])-1); |
44 | 59 | } |
45 | | - // final step, we need to looking for the longest consecutive sequence |
46 | | - int max=0; |
| 60 | + int max=1; |
47 | 61 | for (int x: start.values()) |
48 | 62 | { |
49 | | - max=max>x?max:x; |
50 | | - } |
51 | | - for (int x: end.values()) |
52 | | - { |
53 | | - max=max>x?max:x; |
| 63 | + if (x>max) |
| 64 | + { |
| 65 | + max=x; |
| 66 | + } |
54 | 67 | } |
55 | 68 | return max; |
56 | 69 | } |
|
0 commit comments