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.
解法一:用伪哈希表来记录每个数字,然后遍历一遍伪哈希表,找出最长的连续的不为0的长度,即可返回。但是这种方法的缺点:max - min可能会导致溢出,但是数组的长度最多只能放int的范围(0 ~ 2^31),因此,这个方法会导致溢出的可能。
public int longestConsecutive(int[] nums) {
if (nums.length == 0) return 0;
if (nums.length == 1) return 1;
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
if (nums[i] < min) {
min = nums[i];
}
if (nums[i] > max) {
max = nums[i];
}
}
long number = (long)max - (long)min + 1;
int[] helper = new int[number];
for (int i = 0; i < nums.length; i++) {
helper[nums[i] - min]++;
}
int i = 0,result = 0;
while (i < helper.length) {
if (helper[i] != 0) {
int length = 0;
while (i < helper.length && helper[i++] != 0) {
length++;
}
if (length > result) {
result = length;
}
} else {
i++;
}
}
return result;
}
解法二:HashMap,key存num值,value存这个num值可以组成的最长的连续子数组的长度,因此,每次update num的value值为(left + right + 1),left表示num = left时候的最长子数组长度,right表示num = right的时候最长子数组的长度,遍历数组同时maintain max的值,最后返回max即可。注意重复元素的处理!
public int longestConsecutive(int[] nums) {
if (nums.length == 0) return 0;
HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
int max = 0;
for (int i = 0; i < nums.length; i++) {
if (!map.containsKey(nums[i])) {
int num = nums[i];
int left = map.containsKey(num - 1) ? map.get(num - 1) : 0;
int right = map.containsKey(num + 1) ? map.get(num + 1) : 0;
int sum = left + right + 1;
if (sum > max) max = sum;
//记住这里一定要把正在遍历的元素也po进去,为了保证下一次遍历此元素的时候可以跳过。
map.put(num, sum);
map.put(num - left, sum);
map.put(num + right, sum);
}
}
return max;
}
解法三:(最优解法)用hashset,首先可以完成元素去重的功能,其次,遍历数组,每次po出这个数字,如果可以po出,那么就顺带po出所有可能的连续的周边数组直到找不到为止,同时更新最大的max值,最后返回max值。
public int longestConsecutive(int[] nums) {
if (nums.length == 0) return 0;
HashSet<Integer> set = new HashSet<Integer>();
int max = 0;
for (int i : nums) set.add(i);
for (int i : nums) {
if (set.remove(i)) {
int pre = i - 1, next = i + 1;
while (set.remove(pre)) pre--;
while (set.remove(next)) next++;
if (next - pre - 1 > max) max = next - pre - 1;
}
}
return max;
}