【LeetCode 128 Longest Consecutive Sequence】

博客围绕给定的无序整数数组,探讨如何找出其中最长连续元素序列的长度,要求算法复杂度为O(n)。给出了两种解法,包括朴实的Hash想法和使用unordered_map的正确解法,还对unordered_map在OJ上速度较慢及O(n)时间复杂度证明提出疑问。

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

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

Your algorithm should run in O(n) complexity.

Example:

Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

 

Solution1:(朴实的Hash想法,空间复杂度。。。过大)

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int maxVal = INT_MIN, minVal = INT_MAX;
        int len = nums.size();
        int count = 0;
        
        if(len > 0){
            for(int i = 0; i < len; i++){
                maxVal = max(maxVal, nums[i]);
                minVal = min(minVal, nums[i]);
            }
            int hashT[maxVal-minVal+1];
            for(int i = 0; i < maxVal-minVal+1; i++)
                hashT[i] = 0;
            for(int i = 0; i < len; i++){
                hashT[nums[i]-minVal] = 1;
            }
            
            for(int i = 0; i < maxVal-minVal+1; i++){
                if(hashT[i] == 1){
                    int curCount = 1;
                    int j = i+1;
                    while(j < maxVal-minVal+1 && hashT[j] == 1){
                        curCount++;
                        j++;
                    }
                    count = max(count, curCount);
                    i = j;      
                }
            }
        }
        
        return count;
        
    }
};

Solution2:unordered_map【正确解法】

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        map<int, int> hashT;
        int maxSubseq = 0;
        int len = nums.size();
        
        if(len > 0){
            for(int i = 0; i < len; i++){
                auto it = hashT.find(nums[i]);
                if(it != hashT.end())
                    continue;
                auto it1 = hashT.find(nums[i]-1);
                auto it2 = hashT.find(nums[i]+1);
                
                int left = ( it1 == hashT.end() ? 0 : hashT[nums[i]-1] );
                int right = ( it2 == hashT.end() ? 0: hashT[nums[i]+1] );
                
                int curLen = left + right + 1;
                hashT[nums[i]] = curLen;
                
                hashT[nums[i]-left] = curLen;
                hashT[nums[i]+right] = curLen;
                maxSubseq = max(maxSubseq, curLen);
                
            }
        }
        return maxSubseq; 
    }
};

unordered_map理论上应该更快,但OJ上反而慢了不少??O(n)的时间复杂度证明?

### LeetCode128题 Python 解法 对于LeetCode128题——最长连续序列(Longest Consecutive Sequence),一种有效的解决方案是利用哈希表来实现。这种方法的时间复杂度为O(n)[^5]。 算法的主要思路是在遍历数组的同时,使用集合(set)存储所有的数。这样可以在常量时间内判断某个数值是否存在。为了找到最长的连续序列,针对每一个数字num,在集合中寻找num+1, num+2...直到找不到为止;同时也向负方向探索num-1, num-2...停止条件同样是遇到不存在于集合中的值。但是这种双向扩展的方式存在大量冗余计算,因为如果已经从较小的那个起点开始计算过一次完整的序列,则后续再碰到这个区间内的其他点时无需再次展开搜索。 优化后的策略是从仅从未被访问过的端点出发尝试构建可能存在的最大长度链路,并标记沿途经过的所有节点防止重复处理。具体做法如下: ```python def longestConsecutive(nums): longest_streak = 0 num_set = set(nums) for num in num_set: if num - 1 not in num_set: # 只有当当前数字是潜在序列最小值的时候才进入此逻辑 current_num = num current_streak = 1 while current_num + 1 in num_set: current_num += 1 current_streak += 1 longest_streak = max(longest_streak, current_streak) return longest_streak ``` 上述代码通过只对可能是新序列起始位置的元素执行内部循环,从而大大减少了不必要的运算次数[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值