【LeetCode】Longest Consecutive Sequence解题笔记

题意:给出一个无序的整型数组,求出最长的连续整数序列,例如[100, 4, 200, 1, 3, 2],的最长连续序列为[1,2,3,4],返回序列长度4即可

分析:这个题目如果数组是有序的,则一次遍历就可以得到最长的连续整数长度,但是,题目给出的是无序的序列,因此,第一个思路就有了

思路1:先对数组进行排序(增序或者减序均可),然后遍历数组,如果相邻两个元素的差值为1(增序)或者-1(减序),则在求出的序列长度上+1即可。

这个时候,忽然看到,题目要求,时间复杂度为O(N),思路1就不符合要求了,因为排序的复杂度,最少也是O(NlgN),是不满足要求的,因此,不能花时间对序列进行排序。

排除掉思路1,就开始思考不排序的情况下,如何判断数组中的数字的连续性。所谓连续,也就是这个数字+1或者-1,例如跟1连续的只有0与2,那要判断连续,就只需要考虑0与2是否在当前的数组里即可。于是就有了思路2.

思路2:遍历数组,每一个值val,判断val+1与val-1是否在数组里,但是,查找的时间复杂度,也至少是O(N),这样也是不行的,那就思考,如何把查找的复杂度降低到常量级别,想了很久都没结果,最后,参考了hash的思想,用空间来换取时间,将数组中的数散列到hash表中,即可以常量O(1)的时间复杂度来判断数值的存在与否。

思路2可以满足N的时间复杂度,但是,hash要自己写,其实也挺麻烦的,研究了stl,才发现有现成的数据结构unordered_set与unordered_map,这两个数据结构均是以hash方式来做存储与检索,我们这个题目中不需要保存映射关系,因此选用unordered_set作为hash的载体。

同时还有一个细节,就是检索的时候,是两个方向的,递增与递减,刚开始,我只向一个方向检索,hash表一直不变,导致许多重复的搜索,提交代码时,有超时的错误,后面改进为向两个方向同时检索,并且,检索到一个数值之后,将该数值从hash表中清除,最终才AC通过。


代码:

class Solution {
public:
    int longestConsecutive(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
		unordered_set<int> hashlist = unordered_set<int>();
		for (int i = 0; i < num.size(); ++ i)
		{
			hashlist.insert(num[i]);
		}

		int maxCon = 0;
		for (int i = 0; i < num.size(); ++i)
		{
			int sub = num[i]-1;
			int tmpLen = 1;
			while (hashlist.find(sub) != hashlist.end())
			{
				tmpLen ++;
				hashlist.erase(sub);
				sub--;
			}
			int add = num[i]+1;
			while(hashlist.find(add) != hashlist.end())
			{
				tmpLen ++;
				hashlist.erase(add);
				add ++;
			}
			if (tmpLen > maxCon)
			{
				maxCon = tmpLen;
			}
		}		
		return maxCon;   
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值