[LeetCode132]Longest Consecutive Sequence

本文介绍了一种寻找整数数组中最长连续元素序列的算法,并提供C++与Java两种语言的实现方式。该算法通过哈希表(HashMap)来达到O(n)的时间复杂度。

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

Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Your algorithm should run in O(n) complexity.

Analysis

Note that it is not the classic DP problem, while this problem tests the data structure other than algorithm.

If there is no O(n) requirement, just sort the array (O(n log n)), then find then longest sequence.
But now, the time is required O(n), first of all, what comes to mind immediately is HASH MAP!!!
Yes, because the hash map search the key->value on O(1). Note that in C++ STL, the map data structure is implemented by BST, so the insert in O(log n), therefore we need to use the unordered_map, which has a O(1) complexity.

We first construct hash map for the array,  then for each element, search 2 directions, +1 and -1. If there is no +1 and -1 in the array, length is 1, remove this from map and go to next element in the array. Save the max length.

In C++ map data structure, .find() returns .end() iterator if not find, and if we use (mp[num[i]]==false), when num[i] key is not in the map, the program will insert the key into the map with a default value, here is false.

C++实现如下

int longestConsecutive(vector<int> &num) {
    unordered_map<int, int> contentMap;
    for(int i=0; i<num.size(); i++)
        contentMap[num[i]] = 1;
    int result = 0;
    for(int i=0; i<num.size();i++){
        if(contentMap[num[i]]==1){

            int len =1;
            int left = num[i]-1;
            int right = num[i]+1;
            while(contentMap[left]){
                contentMap[left--] = 0;
                len++;

            }
            while(contentMap[right]){
                len++;
                contentMap[right++] = 0;
            }
            if(len>result) result = len;
        }
    }
    return result;
}


java :


public int longestConsecutive(int[] num) {
        int result = 0;
        Set<Integer> contentMap = new HashSet<Integer>();
        for(int i=0; i<num.length; i++){
        	contentMap.add(num[i]);
        }
        for(int i=0; i<num.length; i++){
        	if(contentMap.contains(num[i])){
        		int len = 1;
        		int left = num[i]-1;
        		int right = num[i]+1;
        		while(contentMap.contains(left)){
        			contentMap.remove(left);
        			len++;
        			left--;
        		}
        		while(contentMap.contains(right)){
        			contentMap.remove(right);
        			len++;
        			right++;
        		}
        		if(len>result)
        			result = len;
        	}
        }
        return result;
    }
可能会有重复元素
<think>好的,我现在需要帮助用户理解他们提供的C++代码段。首先,我会仔细阅读代码,看看它做了什么。 代码中有两个部分:首先声明了一个`unordered_set<int> num_set;`,然后遍历`nums`中的每个元素,将它们插入到`num_set`中。作者是力扣官方题解,可能这段代码是用于解决最长连续序列问题的。 用户可能想知道这段代码的作用以及它在特定问题中的用途。需要解释`unordered_set`的特点,比如快速查找、去重等。然后循环部分,将`nums`中的每个元素插入到集合中,这样可以去重,并为后续的查找操作做准备。 接下来要考虑用户可能的背景。可能是刚开始学习C++或者算法,对STL容器不熟悉。需要用简单易懂的语言解释,避免使用过多术语,但又要准确。比如,解释`unordered_set`是基于哈希表实现的,插入和查找的平均时间复杂度是O(1),这样在处理大量数据时效率高。 然后,这段代码可能出现在最长连续序列的问题中,比如LeetCode 128题。那个问题需要找到一个未排序数组中数字连续的最长序列的长度。通常的解法是先利用集合去重,然后遍历每个数字,检查是否是序列的起点,再逐次查找下一个数字是否存在。因此,这个`num_set`的创建是为了后续的查找操作,提高效率。 用户可能没有说明具体的应用场景,但根据代码来源,可以推测是用于这个问题。需要指出这段代码的作用是预处理数据,去重并存储在哈希集合中,以便快速查询。 另外,需要注意代码中的细节,比如循环中使用`const int& num`来避免不必要的拷贝,提高效率。虽然对于基本类型int来说,用不用引用区别不大,但这也是一种良好的编程习惯。 最后,要确保解释清晰,结构合理,先介绍代码的结构,再解释每个部分的作用,最后联系到实际问题中的应用,帮助用户全面理解。</think>这段代码的作用是**将数组 `nums` 中的所有元素存入一个哈希集合(`unordered_set`)中,实现去重和快速查找**。以下是逐行解析: --- ### 代码解析 ```cpp unordered_set<int> num_set; // 1. 声明一个无序集合(基于哈希表实现) for (const int& num : nums) { // 2. 遍历数组 nums 中的每个元素 num num_set.insert(num); // 3. 将 num 插入集合(自动去重) } ``` --- ### 关键点说明 1. **`unordered_set` 的特性**: - **去重**:若 `nums` 中有重复元素,集合中只会保留一个。 - **快速查找**:基于哈希表实现,插入和查找的平均时间复杂度为 $O(1)$。 - **无序存储**:元素不按顺序存储(与 `set` 不同)。 2. **循环的作用**: - 将数组 `nums` 的每个元素存入集合,为后续操作(如“检查某个值是否存在”)做准备。 --- ### 典型应用场景(如 LeetCode 128. 最长连续序列) 在这类问题中,这段代码常用于: 1. **去重**:避免重复元素干扰连续序列的计算。 2. **快速查询**:后续通过 `num_set.count(num+1)` 等操作,快速判断某个值是否存在,从而统计连续序列长度。 --- ### 代码对比:为什么用 `unordered_set` 而不是其他容器? | 容器 | 特点 | |------------------|---------------------------------------------------------------------| | `vector` | 不去重,查找效率低($O(n)$) | | `set` | 自动排序,但插入和查找效率为 $O(\log n)$ | | `unordered_set` | 无序,但插入和查找效率最高($O(1)$),**最适合当前需求** | --- ### 示例说明 假设输入 `nums = [3, 1, 2, 2, 4]`,执行代码后: - `num_set` 中的内容为 `{1, 2, 3, 4}`(去重且无序存储)。 - 后续可通过 `num_set.find(3)` 快速判断数字 `3` 是否存在。 --- ### 总结 这段代码是**预处理数据的常见操作**,核心目的是通过哈希集合实现: 1. 去重 2. 为后续高频查找提供 $O(1)$ 时间复杂度的支持
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值