Given
[100, 4, 200, 1, 3, 2]
,The longest consecutive elements sequence is
[1, 2, 3, 4]
. Return its length: 4
.I. Intuitive Solution
For each element e we check that if e is visited . If not, we check the length of the sequence ends at e-1, and length of the sequence starts at e+1, then combine these 2 sequence. (Note that we only update the 2 ends of the sequence).
The following solution using 3 HashMap !!! To see why the "visited" HashMap needed, you can check on the following test case:
[-6,8,-5,7,-9,-1,-7,-6,-9,-7,5,7,-1,-8,-8,-2,0]
Take your time! ^_^
- public class Solution {
- public int longestConsecutive(int[] nums) {
- int maxLength = 0;
- Map<Integer, Integer> map1 = new HashMap<Integer, Integer>();
- Map<Integer, Integer> map2 = new HashMap<Integer, Integer>();
- Map<Integer, Boolean> visited = new HashMap<Integer, Boolean>();
- int left, right, l;
- for(int i = 0; i < nums.length; i++){
- if(visited.containsKey(nums[i])) continue;
- visited.put(nums[i], true);
- left = right = nums[i];
- if(map1.containsKey(nums[i]-1))
- left -= map1.get(nums[i]-1);
- if(map2.containsKey(nums[i] + 1))
- right += map2.get(nums[i]+1);
- l = right - left + 1;
- if(maxLength < l) maxLength = l;
- map1.put(right, l);
- map2.put(left, l);
- }
- return maxLength;
- }
- }
With the above code, we can reduce the space to only 1 HashMap.
- public class Solution {
- public int longestConsecutive(int[] num) {
- int longest = 0;
- Map<Integer, Integer> map = new HashMap<Integer, Integer>();
- for(int i = 0;i < num.length;i++){
- // if there is no duplicates, these two lines can be commented
- if(map.containsKey(num[i])) continue;
- map.put(num[i],1);
- int end = num[i];
- int begin = num[i];
- if(map.containsKey(num[i]+1))
- end = num[i] + map.get(num[i]+1);
- if(map.containsKey(num[i]-1))
- begin = num[i] - map.get(num[i]-1);
- longest = Math.max(longest, end-begin+1);
- map.put(end, end-begin+1);
- map.put(begin, end-begin+1);
- }
- return longest;
- }
- }
III. The same idea as the II) approach can be expressed as the following code:
- public class Solution {
- public int longestConsecutive(int[] num) {
- int res = 0;
- HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
- for (int n : num) {
- if (!map.containsKey(n)) {
- int left = (map.containsKey(n - 1)) ? map.get(n - 1) : 0;
- int right = (map.containsKey(n + 1)) ? map.get(n + 1) : 0;
- // sum: length of the sequence n is in
- int sum = left + right + 1;
- map.put(n, sum);
- // keep track of the max length
- res = Math.max(res, sum);
- // extend the length to the boundary(s)
- // of the sequence
- // will do nothing if n has no neighbors
- map.put(n - left, sum);
- map.put(n + right, sum);
- }
- else {
- // duplicates
- continue;
- }
- }
- return res;
- }
- }
IV. Better solution
- public class Solution {
- public int longestConsecutive(int[] num) {
- int longest = 0;
- Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
- for(int i = 0; i< num.length; i++){
- map.put(num[i], false);
- }
- int l, k;
- for(int i = 0;i < num.length;i++){
- if(map.containsKey(num[i]-1) || map.get(num[i])) continue;
- map.put(num[i], true);
- l = 0; k = num[i];
- while (map.containsKey(k)){
- l++;
- k++;
- }
- if(longest < l) longest = l;
- }
- return longest;
- }
- }
No comments:
Post a Comment