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

常用算法里的细节

👨‍💻 关于作者:会编程的土豆

“不是因为看见希望才坚持,而是坚持了才看见希望。”

你好,我是会编程的土豆,一名热爱后端技术的Java学习者。

📚正在更新中的专栏:

  • 《数据结构与算法》😊😊😊

  • 《leetcode hot 100》🥰🥰🥰🤩🤩🤩

  • 《数据库mysql》

💕作者简介:后端学习者

LCS模版(最长公共子序列(Longest Common Subsequence))

仅求长度

  • 若字符相等:dp[i][j] = dp[i-1][j-1] + 1

  • 若字符不等:dp[i][j] = max(dp[i-1][j], dp[i][j-1])

int longestCommonSubsequence(string text1, string text2) { int n = text1.size(), m = text2.size(); vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0)); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (text1[i - 1] == text2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } } } return dp[n][m]; }

这里注意因为i,j记录的是前s的i个字符和t的前j个字符中的公共子序列,由于字符下标是从0开始的,所以实际上i只记录到下标为i-1的数,j也是同理;所以if对比的时候记得是对比s[i-1]==t[j-1];记得要减一;

回溯具体子序列

在 DP 填表完成后,从右下角(n, m)倒推回去

string getLCS(string text1, string text2) { int n = text1.size(), m = text2.size(); vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0)); // 1. 填表 for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { if (text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } } // 2. 回溯构建 LCS 字符串 string lcs; int i = n, j = m; while (i > 0 && j > 0) { // 如果字符相等,它是LCS的一部分,往左上移动 if (text1[i - 1] == text2[j - 1]) { lcs.push_back(text1[i - 1]); i--; j--; } // 如果不相等,走向数值较大的那个方向 else if (dp[i - 1][j] > dp[i][j - 1]) { i--; } else { j--; } } reverse(lcs.begin(), lcs.end()); return lcs; }

LIS(最长上升子序列(Longest Increasing Subsequence, LIS))

这个是求一个字符串中或者数组中最长上升的那个子序列;

元素可以一样的用upper_bound

vector<int>tail; for (int i = 0; i < arr.size(); i++) { int x = arr[i]; auto it = upper_bound(tail.begin(), tail.end(), x); if (it == tail.end()) { tail.push_back(x); } else *it = x; } cout << tail.size() << endl;

这个是求arr数组的最长可以一样元素的最长子序列;

元素不可以一样的用lower_bound

vector<int>tailb; for (int i = 0; i < arr.size(); i++) { int x = arr[i]; auto it = lower_bound(tailb.begin(), tailb.end(), x); if (it == tailb.end()) { tailb.push_back(x); } else *it = x; } cout << tailb.size() << endl;

这个是求arr数组的最长子序列,必须严格递增;

你想要的子序列类型应该用的函数原因
严格递增(不能相等)lower_bound找第一个>= x的位置,会替换掉相等的元素,阻止重复
非严格递增(允许相等)upper_bound找第一个> x的位置,保留相等的元素,允许重复

注意里面的操作都是关于tail数组的操作,tail数组就是记录最长子序列元素的数组,而且是保证里面的每个值尽可能小;

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

相关文章:

  • 一文搞懂:开发环境配置进化史——从Maven到Nacos再到Docker
  • 你的微信聊天记录值得永久珍藏吗?WeChatMsg开源工具实现数据自主管理
  • 精准管控付款!融智天合同管理系统应付统计功能实测 - 业财科技
  • Python依赖地狱实战:如何在不降级gradio-client的情况下,修复Gradio的JSON Schema解析Bug
  • 如何用Python在5分钟内批量获取B站视频的精确数据?
  • RT-Thread BSP制作避坑指南:从Kconfig配置到SCons脚本的完整实战(STM32平台)
  • Pixel Language Portal 物联网(IoT)应用:为嵌入式设备生成轻量级通信协议解析代码
  • 为什么市面AI视频工具,都不适合做课程?
  • 文化与科技共生,让超元力XR剧场在沉浸中焕发新生
  • Next.js 14中的数据传递:服务器与客户端的完美协作
  • 从‘運’字说起:GBK编码、PHP转义函数与MySQL连接层的安全三角关系
  • **边缘Ai新范式:基于Python的轻量级模型部署实战与优化策略**在人工智能飞
  • #官方认证|2026年国内六大正规水分仪 / 面密度仪公司排名,广东佛山等地,巢目科技技术领先实力强 - 十大品牌榜
  • 腾讯地图 智能硬件定位
  • 终极指南:用TrafficMonitor插件将Windows任务栏变成全能监控中心
  • 2025平航杯(持续更新)
  • 电商数据采集不稳定?试试企业级授权 API 通道,高并发不风控
  • XUnity.AutoTranslator终极指南:3种方法让Unity游戏实时翻译无障碍
  • CDH 6.3.2 集群部署实战:从零到一构建企业级大数据平台
  • 三国地理与战略推演:从地图视角解析关键战役的胜负手
  • RabbitMQ 高可用:如何创建镜像队列?镜像队列原理+完整创建流程+实战配置
  • #官方认证|2026年国内六大正规瑕疵检测CCD公司排名,巢目科技技术实力遥遥领先,广东佛山等地 - 十大品牌榜
  • 有人还在硬卷CRUD,有人早已靠工具吃肉
  • PHP源码开发用台式机还是笔记本更合适_硬件选型对比【方法】
  • 筑牢合规防线!融智天合同管理系统合规与审计功能实测 - 业财科技
  • 如何在Windows任务栏打造实时股票监控系统:TrafficMonitor股票插件终极指南 ✨
  • #官方认证|2026年国内六大正规克重仪公司排名,广东佛山等地,巢目科技综合实力遥遥领先 - 十大品牌榜
  • Qwen3-14B RTX 4090D镜像:显存碎片整理策略与长期运行稳定性验证
  • 包装设计外包如何选?这几家公司值得考虑
  • 如何在Navicat中使用逻辑模型转为物理模型_架构师必备技能