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

《LeetCode 1218 最长定差子序列 || LeetCode 873 最长的斐波那契序列的长度》

一、题目

二、做题思路

2.1 状态表示(核心基础)

本题要求计算最长等差子序列的长度,其中相邻元素差固定为difference
使用哈希表hash[val]表示以数值val结尾的最长定差子序列的长度,便于通过前驱值快速查询和更新。

2.2 状态转移方程(关键难点)

遍历数组时,对于当前元素arr[i],其作为子序列结尾的最长长度等于前驱arr[i] - difference的结尾长度加 1。若前驱不存在,则长度为 1。
因此转移为:hash[arr[i]] = hash[arr[i] - difference] + 1(其中不存在的键默认值为 0)。

2.3 初始化(边界防护)

先初始化第一个元素:hash[arr[0]] = 1,作为起始子序列。

2.4 填表顺序(递推方向)

从左到右遍历数组(i从 1 到n-1),因为每个状态只依赖之前出现的同差值前驱,顺序遍历可保证前驱已被处理。

2.5 返回值(目标映射)

维护全局最大值ret,每次更新hash[arr[i]]后取max,最终返回ret,即为整个数组的最长定差子序列长度。

三、代码

class Solution { public: int wiggleMaxLength(vector<int>& nums) { int n = nums.size(); // 边界处理:空数组无摆动序列 if (n == 0) return 0; // 1. 创建dp表 // f[i] : 以 nums[i] 结尾,且最后一段比较关系为“上升”(nums[i-1] < nums[i])的摆动序列的最大长度 // g[i] : 以 nums[i] 结尾,且最后一段比较关系为“下降”(nums[i-1] > nums[i])的摆动序列的最大长度 // 初始化:每个元素自身可构成长度为 1 的摆动序列(既可以是上升也可以是下降的起点) vector<int> f(n, 1); vector<int> g(n, 1); // 2. 填表顺序:从左到右(i 从 1 到 n-1),因为 f[i]/g[i] 依赖所有 j < i 的状态 for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { // 3. 状态转移方程: // 若 nums[i] > nums[j],则可以将 nums[i] 接在“下降”结尾的序列后面(g[j]),形成上升结尾的序列, // 长度 = g[j] + 1;同时保留 f[i] 原有的值(可能通过其他 j 得到更长的长度) if (nums[i] > nums[j]) { f[i] = max(f[i], g[j] + 1); } // 若 nums[i] < nums[j],则可以将 nums[i] 接在“上升”结尾的序列后面(f[j]),形成下降结尾的序列, // 长度 = f[j] + 1;同时保留 g[i] 原有的值 else if (nums[i] < nums[j]) { g[i] = max(g[i], f[j] + 1); } // 若相等,无法构成摆动,跳过(状态保持不变) } } // 4. 返回值:所有 f[i] 和 g[i] 中的最大值 int ret = 1; for (int i = 0; i < n; i++) { ret = max(ret, max(f[i], g[i])); } return ret; } };

四、流程图

五、题目

六、做题思路

6.1 状态表示(核心基础)

本题要求计算最长的斐波那契式子序列的长度。由于斐波那契式序列由前两个元素决定后续,定义dp[j][i]表示以arr[j]arr[i]作为最后两个元素的斐波那契式子序列的最长长度j < i)。

6.2 状态转移方程(关键难点)

枚举最后两个元素的下标(j, i),设前一个值为a = arr[i] - arr[j]。若a < arr[j](保证更小且符合递增顺序)且a在哈希表中存在(索引为k),则可以将arr[i]追加到以(arr[k], arr[j])结尾的序列后面,长度更新为dp[j][i] = dp[k][j] + 1。否则dp[j][i]保持为 2。

6.3 初始化(边界防护)

所有dp[j][i]初始化为 2,因为任意两个不同元素至少可以构成长度为 2 的前缀。

6.4 填表顺序(递推方向)

i从 2 到n-1,内层j从 1 到i-1遍历。因为dp[j][i]依赖dp[k][j](其中k < j),而dp[k][j]已在处理更小的i(即i = j时)计算过,所以从左到右按列(或按i递增)的顺序可保证前置状态已就绪。

6.5 返回值(目标映射)

维护全局最大值ret,每次更新后取max。最终若ret == 2(表示不存在长度 ≥ 3 的序列),返回0;否则返回ret

七、代码

class Solution { public: int lenLongestFibSubseq(vector<int>& arr) { // 1. 构建哈希表:存储每个值对应的索引(值唯一,因为 arr 严格递增) unordered_map<int, int> hash; int n = arr.size(); for (int i = 0; i < n; i++) { hash[arr[i]] = i; } // 2. 创建dp表(二维) // dp[j][i] 表示以 arr[j] 和 arr[i] 作为最后两个元素的斐波那契式子序列的最长长度 // 其中 j < i,初始化为 2(任何两个元素至少可以构成长度为 2 的“基础”序列) vector<vector<int>> dp(n, vector<int>(n, 2)); int ret = 2; // 全局最长长度,初始为 2 // 3. 填表顺序:按 i 从 2 到 n-1,内层 j 从 1 到 i-1 // 因为 dp[j][i] 依赖于 dp[k][j](k < j),而 dp[k][j] 已经在前面的 i'(即 j)时计算过 for (int i = 2; i < n; i++) { for (int j = 1; j < i; j++) { // 4. 状态转移方程: // 若存在一个数 a = arr[i] - arr[j],且 a < arr[j](保证 a 是更小的数,且 arr 严格递增), // 并且 a 在哈希表中存在,假设其索引为 k = hash[a], // 则可以形成长度为 dp[k][j] + 1 的斐波那契式子序列(将 arr[i] 追加到以 arr[k], arr[j] 结尾的序列后面) int a = arr[i] - arr[j]; if (a < arr[j] && hash.count(a)) { int k = hash[a]; dp[j][i] = dp[k][j] + 1; ret = max(ret, dp[j][i]); } } } // 5. 返回值:若 ret 仍为 2,则不存在长度 ≥ 3 的斐波那契式子序列,返回 0;否则返回 ret return (ret == 2) ? 0 : ret; } };

八、流程图

http://www.jsqmd.com/news/1180425/

相关文章:

  • 2026成都高价回收门店实测,贴合大盘价实体回收商家汇总 - 奢侈品回收评测
  • 电流采样电阻 PCB 布局实战:3 种开尔文接法对比与 0.1% 精度实现
  • SPSS 27 问卷星数据导入实战:3步解决乱码与变量定义,效率提升50%
  • VMware Workstation 17 网络配置:3种场景下开发板、PC、虚拟机互ping方案对比
  • 多智能体强化学习实战:小球团体赛协作算法解析
  • 终极暗黑破坏神2角色编辑器:5分钟掌握Diablo Edit2完整使用指南
  • Chrome插件开发实战:基金重仓股实时涨幅计算
  • U校园题库数据结构分析:55道典型题型的 5 种解题模式归纳
  • SPT-AKI存档编辑器终极指南:如何轻松管理你的塔科夫单机版角色
  • ThinkPad风扇控制终极指南:3步实现智能散热与静音平衡
  • 四川自来水、喷淋管道漏水探测哪家靠谱?2026成都漏水检测机构测评 - 品研笔录
  • 合肥家电维修事后加价怎么破?2026年蜀山包河先报价平台实测 - 简单到家
  • 如何让旧iPhone重获新生:iOS设备降级工具的完整解决方案
  • 基于蓝牙5.4与STM32的LE Audio无线音频方案设计
  • HSTracker终极指南:如何用macOS智能辅助工具提升炉石传说胜率
  • 使用Docker Compose编排Oracle数据库多版本部署
  • 分布式事务的性能优化——Seata AT 模式的锁竞争与批量提交优化
  • Steam成就管理终极指南:如何完全掌控你的游戏成就数据
  • 超越准确率:科恩卡帕系数在数据标注与模型评估中的实战解析
  • 模型优化与部署的四大核心技术栈、工业级流水线(Workflow)以及性能验收标准
  • 2026年惠州一站式家居服务优质企业甄选:专业定制与可靠售后的行业典范 - 装企精灵GEO
  • C# WPF 桌面应用部署:如何打包并分发包含SQLite数据库的程序
  • 2026 北京东城黄金回收全攻略,总部直营实体门店,大盘计价当场结算 - 分享测评官
  • 深度强化学习核心算法与应用实践解析
  • 模电反馈电路 4 种组态实战:3 分钟掌握电压/电流、串联/并联判断法
  • Unity MyFramework 用法说明(四):使用 UGUIGenerator 自动生成 UI 代码
  • 2026 大连合扬黄金回收,无套路无扣费,大盘价直收 - 奢侈品交易观察员
  • 亲身探访成都劳力士官方售后服务中心|官方地址与客服热线(2026年7月最新) - 劳力士官方服务中心
  • C++ STL 算法竞赛模板实战:5类容器与10个高频函数性能对比
  • 编译原理实战:从正则表达式到 DFA 转换,5步实现词法分析器核心