ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

128. 最长连续序列

2021-09-06 21:59:42  阅读:114  来源: 互联网

标签:hash cur 序列 length num dict 128 长度 最长


128. 最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

哈希表

我们考虑枚举数组中的每个数 x x x​​, 考虑以其为起点, 不断尝试匹配 x + 1 , x + 2 , ⋯ x+1, x+2, \cdots x+1,x+2,⋯​​ 是否存在,假设 最长匹配到了 x + y x+y x+y​​, 那么以 x x x​​ 为起点的最长连续序列即为 x , x + 1 , x + 2 , ⋯   , x + y x, x+1, x+2, \cdots, x+y x,x+1,x+2,⋯,x+y​​, 其长度为 y + 1 y+1 y+1​​, 我们不断枚举并更新答案即可。

对于匹配的过程用一 个哈希表存储数组中的数, 这样查看一个数是否存在即能优化至 O ( 1 ) O(1) O(1)​​ 的时间复杂度。

img

仅仅是这样我们的算法时间复杂度最坏情况下还是会达到 O ( n 2 ) O\left(n^{2}\right) O(n2)​​ (即外层需要枚举 O ( n ) O(n) O(n)​​ 个数, 内层 需要暴力匹配 O ( n ) O(n) O(n)​​ 次),无法满足题目的要求。但仔细分析这个过程,我们会发现其中执行了很 多不必要的枚举, 如果已知有一个 x , x + 1 , x + 2 , ⋯   , x + y x, x+1, x+2, \cdots, x+y x,x+1,x+2,⋯,x+y​​ 的连续序列,而我们却重新从 x + 1 x+1 x+1​​, x + 2 x+2 x+2​​ 或者是 x + y x+y x+y​​ 处开始尝试匹配,那么得到的结果肯定不会优于枚举 x x x​​ 为起点的答案,因此我们 在外层循环的时候碰到这种情况跳过即可。

那么怎么判断是否跳过呢?由于我们要枚举的数 x x x​​ 一定是在数组中不存在前驱数 x − 1 x-1 x−1​​ 的,不然按 照上面的分析我们会从 x − 1 x-1 x−1​​ 开始尝试匹配,因此我们每次在哈希表中检查是否存在 x − 1 x-1 x−1​​​ 即能判断是否需要跳过了。

img

class Solution:
    def longestConsecutive(self, nums):
        longest_streak = 0
        num_set = set(nums) 

        for num in num_set: 
            if num - 1 not in num_set: # 不存在前驱数 x-1
                current_num = num      # 当前匹配数字
                current_streak = 1     # 当前匹配长度

                while current_num +1 in num_set: # 查看x+1是否在哈希表中
                    current_num +=1           # 当前匹配数字 x+1
                    current_streak +=1         # 当前匹配长度 +1
                
                longest_streak = max(longest_streak, current_streak)

        return longest_streak

  • 用哈希表存储每个端点值对应连续区间的长度
  • 若数已在哈希表中:跳过不做处理
  • 若是新数加入:
    • 取出其左右相邻数已有的连续区间长度 left 和 right
    • 计算当前数的区间长度为:cur_length = left + right + 1
    • 根据 cur_length 更新最大长度 max_length 的值
    • 更新区间两端点的长度值

示例图解

class Solution(object):
    def longestConsecutive(self, nums):
        hash_dict = dict()
        max_length = 0
        for num in nums:
            if num not in hash_dict:
                # 判断左右是否可以连起来
                left = hash_dict.get(num - 1, 0)
                right = hash_dict.get(num + 1, 0)
                # 记录长度
                cur_length = 1 + left + right
                if cur_length > max_length:
                    max_length = cur_length
                
                hash_dict[num] = cur_length
                # 把头尾都设置为最长长度
                hash_dict[num - left] = cur_length
                hash_dict[num + right] = cur_length
            
        return max_length

参考

Krahets - 力扣(LeetCode) (leetcode-cn.com)

标签:hash,cur,序列,length,num,dict,128,长度,最长
来源: https://blog.csdn.net/qq_43940950/article/details/120145838

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有