LeetCode 128 最长连续序列

本文介绍了一种使用HashMap解决寻找未排序整数数组中最长连续序列的问题的方法,通过一次遍历实现了O(n)的时间复杂度,适用于大规模数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

    给定一个未排序的整数数组,找出最长连续序列的长度。

    要求算法的时间复杂度为 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;
	}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值