题目:
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
思路解析:由于题目要求算法的时间复杂度是O(n),所以用一般的排序算法解决不了。我在这里使用的是HashMap数据结构来解决问题的。HashMap中的key表示数组中每个元素的值,value对应的是数组中每个元素key连续序列的长度。
首先遍历数组nums[i],将数组中每一个元素插入到HashMap去,这个时候存在以下几种情况:
(1)、插入HashMap中该元素已经存在,则不插入。
(2)、插入HashMap中该元素不存在且该元素没有相邻的元素,则key=nums[i],value=1插入到HashMap中去即可。
(3)、插入HashMap中某元素时,有比它大的相邻的元素,则一直遍历找到与它相邻序列中最大的那个元素,然后将连续序列的首尾key对应的value更新为连续序列的长度即可。
(4)、插入HashMap中某元素时,有比它小的且相邻的元素,则一直遍历HashMap找到与它相邻序列中最小的那个元素,然后将连续序列首尾的Key对应的value更新为最新的连续序列的长度个数即可。
(5)、插入HashMap中某元素时,有比它大的相邻的元素,也有比它小的相邻的元素,则我们先遍历HashMap找到与它相邻且比它大的序列中最大的那个元素,然后将连续序列的首尾key对应的value更新为最新的连续序列的长度;然后遍历HashMap找到与它相邻且比它小的序列中最小的那个元素,然后将最长的连续序列的首尾的Key对应的value更新为序列的长度即可。
代码:
import java.util.HashMap;
import java.util.Map;
/**
* 给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
* @author ting.wang
*
*/
public class LeetCode128 {
public static void main(String[] args) {
int []nums= {1,3,2};
System.out.println(getMaxSortNum(nums));
}
public static int getMaxSortNum(int []nums) {
if(nums==null||nums.length==0) { //判断边界条件
return 0;
}
//key是nums数组的值,value对应的是每一个nums[i]处连续的序列的个数
Map<Integer,Integer> param=new HashMap<>();
for(int i=0;i<nums.length;i++) {
if(!param.containsKey(nums[i])) { //hashMap中没有该元素的时候。
param.put(nums[i], 1); //初始化认为与该元素相邻的只有一个。
int temp=nums[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(nums[i], param.get(temp)); //更新当前元素的value,保证一个连续序列的最前和最后一个元素的value值相同
flag=true;
}
int temp2=nums[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(nums[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;
}
}