2018-11-25 16:28:09
问题描述:
问题求解:
方法一、如果不要求是线性时间的话,其实可以很直观的先排序在遍历一遍就可以得到答案,但是这里明确要求是O(n)的时间复杂度,那么就给了一个强烈的提示就是使用Hash来进行解决。方法一的思路很明确也很暴力,就是将所有的数字都保存到一个Hash表中,如果当前的数字是首个元素,那么就从他开始往后串连,得到以当前数字为首的最长连续序列,最后取max即可。时间复杂度是O(n),因为至多只会读取一个元素两次。
public int longestConsecutive(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int res = 0;
Set<Integer> set = new HashSet<>();
for (int i : nums) set.add(i);
for (int i : nums) {
if (set.contains(i - 1)) continue;
int len = 1;
while (set.contains(i + 1)) {
len++;
i++;
}
res = Math.max(res, len);
}
return res;
}
方法二、这个解法就难思考到一点,当然了依然是使用hash,只是这次保存的以当前为末尾的最长的序列的长度,之后如果重复读取则直接过滤掉,如果不是重复元素,那么就需要对其进行判断,如果左右有元素那么就会生成新的长度的序列,最后只需要遍历一遍hash即可。
public int longestConsecutive(int[] nums) {
if (nums.length == 0 || nums.length == 1) return nums.length;
int res = 0;
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
if (map.containsKey(num)) continue;
int l = map.getOrDefault(num - 1, 0);
int r = map.getOrDefault(num + 1, 0);
int len = l + r + 1;
if (l != 0 && r != 0) {
map.put(num - l, len);
map.put(num + r, len);
}
else if (l != 0) {
map.put(num - l, len);
}
else if (r != 0) {
map.put(num + r, len);
}
map.put(num, len);
}
for (int key : map.keySet()) res = Math.max(res, map.get(key));
return res;
}