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;
}
}
II. Improvement on the code 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