题目:
给定一个无序的整数类型数组,求最长的连续元素序列的长度。
例如:
给出的数组为[100, 4, 200, 1, 3, 2],
最长的连续元素序列为[1, 2, 3, 4]. 返回这个序列的长度:4
你需要给出时间复杂度在O(n)之内的算法。
本题是利用HashMap数据结构来解决问题的。
普及一下HashMap:
Hash: 散列
Map:意思是地图(x,y)存储值
HashMap 是一个采用hash表实现键值对集合,继承 AbstractMap,实现了Map接口。在这里,HashMap中的key表示数组中每个元素的值,value对应的是数组中每个元素key连续序列的长度。
package com.company;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
/**
* 给定一个未排序的整数数组,找出最长连续序列的长度
* 要求算法的复杂度是 O(n)
*/
public class TestNo6 {
public static void main(String[] args) {
int[] nums = {1, 8, 3, 5, 2, 9};
TestNo6 t = new TestNo6();
System.out.println(t.longestConsecutive(nums));
}
public int longestConsecutive(int[] num) {
if (num == null || num.length == 0) { //判断边界条件
return 0;
}
//key 是num数组的值,value对应的是每一个num[i]初连续的序列的个数
Map<Integer, Integer> param = new HashMap<Integer, Integer>();
for (int i = 0; i < num.length; i++) {
if (!param.containsKey(num[i])) { //hashMap中没有该元素的时候
param.put(num[i], 1); //初始化认为与该元素相邻的只有一个
int temp = num[i]; //temp用来保存比该元素大的且连续的最大的那个元素
boolean flag = false; //用来判断是否有既有与该元素大的相邻元素,又有比该元素小的相邻元素
if (param.containsKey(temp + 1)) {
while (param.containsKey(temp + 1)) {
temp++;
}
param.put(temp, param.get(temp) + 1); //更新最大的那个元素的value,即连续序列的个数
param.put(num[i], param.get(temp)); //更新当前元素的value,保证一个连续序列的最前和最后一个元素的value值相同
flag = true;
}
int temp2 = num[i]; //用来保存比当前元素小的且连续的那个数
int count = 0; //用来比较比当前元素小的个数
if (param.containsKey(temp2 - 1)) { //如果存在比当前元素小的且连续的元素key
while (param.containsKey(temp2 - 1)) {
temp2--;
count++;
}
if (flag) { //即存在比当前元素大的key又存在比当前元素小的key
param.put(temp, param.get(temp) + count); //更新新的连续序列的首尾
param.put(temp2, param.get(temp));
} else { //只存在比当前元素小的且相邻的元素序列,不存在比当前元素大且相邻的元素key
param.put(temp2, param.get(temp2) + 1); //更新新的连续序列的首尾
param.put(num[i], param.get(temp2));
}
}
}
}
int max = Integer.MIN_VALUE; //用来保存最长连续序列有多少元素
for (Integer key : param.keySet()) {
if (max < param.get(key)) {
max = param.get(key);
}
}
return max;
}
}