当前位置: 首页 > news >正文

pyhton(大厂笔试/面试)最长子序列(哈希-回溯-中等)含源码(二十三)

一、题目(含示例)

问题描述:给定一个未排序的整数数组 nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度,设计算法解决此问题(第二个解法需满足时间复杂度 O (n))。

示例

  1. 输入:nums = [100,4,200,1,3,2],输出:4(最长序列为 [1,2,3,4])。
  2. 输入:nums = [0,3,7,2,5,8,4,6,0,1],输出:9(最长序列为 [0,1,2,3,4,5,6,7,8])。
  3. 输入:nums = [1,0,1,2],输出:3(最长序列为 [0,1,2])。

二、解题关键(难点和核心逻辑)

难点
  • 如何高效判断 “数字连续性”(避免重复计算或遗漏序列)。
  • 平衡时间复杂度:回溯法需枚举所有可能序列(时间复杂度高),哈希表法需通过快速查找优化效率(满足 O (n))。
核心逻辑
  1. 回溯法(解法 1)

    • 先对数组去重、排序(确保连续数字相邻),通过递归 + 回溯枚举所有可能的连续序列,实时更新最长序列长度。
    • 核心:对每个元素,要么 “延续当前序列”(若下一个元素是当前最后元素 + 1),要么 “开启新序列”,通过回溯遍历所有可能性。
  2. 哈希表法(解法 2)

    • 利用集合(哈希表)的 O (1) 查找特性,仅对 “连续序列的起点”(即 num-1 不在集合中)向后延伸,计算序列长度,避免重复处理同一序列。
    • 核心:通过判断 “是否为起点” 减少无效计算,每个元素仅被访问一次,保证 O (n) 时间复杂度。

三、完整代码实现

解法 1:回溯法(不考虑时间复杂度)
from typing import Listclass Solution:def longestConsecutive(self, nums: List[int]) -> int:if not nums:  # 处理空数组return 0max_length = 1  # 初始化最长长度(至少为1)# 去重+排序:确保连续数字相邻,避免重复计算nums = sorted(list(set(nums)))current = [nums[0]]  # 初始序列从第一个元素开始def backtrack(start, current):nonlocal max_length  # 允许修改外部变量max_length# 更新最长长度current_len = len(current)if current_len > max_length:max_length = current_len# 递归终止:遍历完所有元素if start == len(nums):return# 遍历剩余元素,尝试延续或开启新序列for i in range(start, len(nums)):# 若当前元素可延续序列(当前最后元素+1)if current[-1] + 1 == nums[i]:current.append(nums[i])  # 加入序列backtrack(i + 1, current)  # 递归下一个元素current.pop()  # 回溯:恢复状态# 开启新序列(从当前元素开始)new_current = [nums[i]]backtrack(i + 1, new_current)# 从索引1开始遍历,初始序列为[nums[0]]backtrack(1, current)return max_length
解法 2:哈希表法(时间复杂度 O (n))
from typing import Listclass Solution:def longestConsecutive(self, nums: List[int]) -> int:if not nums:  # 处理空数组return 0num_set = set(nums)  # 转为集合:去重+O(1)查找max_length = 1  # 初始化最长长度for num in num_set:# 仅当num是序列起点(num-1不在集合中)时,向后延伸if num - 1 not in num_set:current_num = num  # 当前序列的最后一个数字current_length = 1  # 当前序列长度(初始为1)# 向后查找连续数字,更新长度while current_num + 1 in num_set:current_num += 1current_length += 1# 更新最长长度max_length = max(max_length, current_length)return max_length

四、解题基础知识(代码中函数 / 概念详解)

  1. 列表与集合转换

    • set(nums):将列表转为集合,自动去重(集合元素唯一),时间复杂度 O (n)。
    • list(set(nums)):将集合转回列表(集合无序,需配合排序使用),时间复杂度 O (n)。
  2. 排序函数 sorted()降序排列: sorted(nums,reverse=True)

    • 对列表升序排序,时间复杂度 O (n log n),确保连续数字在列表中相邻(如 [3,1,2] 排序后为 [1,2,3])。
  3. 回溯法核心概念

    • 递归:函数自身调用以探索子问题(如 backtrack(i+1, current) 探索下一个元素)。
    • 状态恢复(current.pop()):在递归返回后移除最后添加的元素,确保后续遍历不被干扰(关键特性)。
    • nonlocal 关键字:允许内部函数(backtrack)修改外部函数(longestConsecutive)中的变量(max_length)。
  4. 集合的查找操作

    • num in num_set:判断元素是否在集合中,时间复杂度 O (1)(哈希表特性),是解法 2 高效的核心。
  5. 循环控制

    • for 循环:遍历集合 / 列表元素(解法 1 中遍历剩余元素,解法 2 中遍历所有去重元素)。
    • while 循环:解法 2 中用于向后延伸连续序列(如从 1 延伸到 2,3,4)。

五、进阶知识

  1. 时间复杂度对比

    • 回溯法:排序占 O (n log n),回溯过程枚举所有可能序列,时间复杂度 O (2ⁿ)(指数级),仅适用于小规模数据(n≤20)。
    • 哈希表法:集合转换 O (n),遍历 + 查找 O (n)(每个元素最多被访问 2 次),总时间 O (n),适用于大规模数据(n≤10⁵)。
  2. 空间复杂度对比

    • 回溯法:递归栈深度 O (n),存储序列需 O (n),总空间 O (n)。
    • 哈希表法:集合存储 O (n),无额外递归空间,总空间 O (n)。
  3. 哈希表的优势

    • 查找、插入、删除操作均为 O (1),适合 “频繁判断元素是否存在” 的场景(如连续序列问题)。
  4. 回溯法的局限性

    • 时间复杂度高,无法处理大规模数据;但适合 “枚举所有可能解” 的场景(如组合、排列问题)。
  5. 连续序列问题的本质

    • 核心是找到 “序列起点”(前一个元素不存在),再延伸计算长度,避免重复处理(两种解法均体现此思路,只是实现方式不同)。

六、提炼解题套路和模板

套路 1:回溯法(枚举所有可能序列)

适用场景:小规模数据、需枚举所有可能解的问题(如组合、连续序列枚举)。

步骤

  1. 预处理数据(去重、排序,减少无效计算)。
  2. 定义递归函数,参数包括 “当前位置” 和 “当前序列”。
  3. 递归逻辑:
    • 终止条件:遍历完所有元素。
    • 选择逻辑:对每个元素,要么 “延续当前序列”(满足连续条件),要么 “开启新序列”。
    • 回溯:修改状态后递归,返回后恢复状态。
  4. 实时更新最优解(如最长长度)。
套路 2:哈希表法(高效查找 + 起点延伸)

适用场景:大规模数据、需 O (n) 时间复杂度的问题(如连续序列、两数之和)。

步骤

  1. 将数组转为集合(去重 + O (1) 查找)。
  2. 遍历集合,筛选 “序列起点”(num-1 不在集合中)。
  3. 对每个起点,向后延伸计算连续序列长度(num+1, num+2,...)。
  4. 记录最长长度,返回结果。

总结:连续序列问题优先用哈希表法(高效),小规模数据或需枚举所有解时用回溯法。核心是通过 “起点判断” 减少无效计算,利用数据结构特性(集合的快速查找)优化效率。

http://www.dtcms.com/a/503608.html

相关文章:

  • 做淘宝浏览单的网站菏泽外贸网站建设公司
  • Linux:理解操作系统和进程
  • 单片机开发工具篇:(六)STM32CubeMX 的使用,包括软件和固件包的下载、以及基础使用
  • 网站建设费是多少常州高端网站建设
  • 20.UE-游戏逆向-绘制所有对象坐标
  • jsp网站建设作业泗阳县建设局网站
  • Springboot整合IoTB
  • 个人做网站哪种类型的网站好男生做男生网站在那看
  • 从 0 到 1 学 C 语言队列:链表底层实现(初始化 / 入队 / 出队 / 销毁),代码可直接复用!
  • 书店网站建设网站栏目结构软文营销的特点有哪些
  • 做个网站要多久做网站app要多少钱
  • 1. Linux 驱动开发前景
  • 深入理解进程生命周期:从 fork 到 exit 的完整旅程
  • 英维克(002837)-2025-10-19
  • 自助手机网站建站软件wordpress metaslider
  • PCIe协议之 Equalization篇 之 FIR 三抽头的三因子的理解
  • FFmpeg 基本API av_seek_frame函数内部调用流程分析
  • FFmpeg 基本API avcodec_send_packet函数内部调用流程分析
  • 手机建站网站常德营销型网站建设
  • Flutter 与原生混合编程
  • DevOps 与 部署入门:加速软件交付与运维的实践指南
  • 优化网站seo中山做百度网站的公司名称
  • 上海袜网站建设电商营业执照
  • 找到K个最接近的元素
  • Java中JDK、JRE、JVM概念
  • MySQL 表操作核心指南:CRUD 与进阶技巧
  • 网站开发个人总结网页设计与网站建设在线考试1
  • 算法笔记 05
  • 游戏科技网站杭州建设工程交易中心网站
  • 网站做推广要备案吗四川seo快速排名