允许跳过元素,不能改变顺序
一个序列的子序列,可以通过删除零个或多个元素得到,剩余元素的先后次序保持不变。最长公共子序列要求结果同时是两个输入的子序列,并使保留长度最大;它不要求这些元素在原文里连续。
例如abc和ac的最长公共子序列是ac,虽然a与c在第一个输入中隔着b。最优结果也可能不唯一;接口返回其中一个解,并不说明其他同样长度的结果错误,更不能据此断言作者真实进行了哪一次编辑。
参考:[1]
用两个剩余后缀定义状态
动态规划可把状态定义为两个剩余后缀的最优长度。若开头元素相同,可以保留这个元素,再求两个后缀各前进一步的结果;若不同,则比较跳过第一边或第二边一个元素后的两种最优长度。
任一后缀为空时,共同子序列长度为零。按依赖顺序填表后,从原始状态沿相容选择前进,就能恢复一个具体结果。状态保存的是最优长度,恢复路径还负责决定究竟输出哪些元素。
长度计算与完整恢复的成本
两个非空输入长度为m、n时,标准二维表有O(mn)个状态,每个只比较常数个已知值,表计算需要O(mn)时间与空间。若只需长度,可以只保留相邻行,把辅助表降为线性空间;这样却不能直接保留所有回溯选择。
这种对齐忽略被删除元素的间隔长度,也没有自动理解语义。把程序标记、文本字符或其他对象当作元素,会得到不同的比较;若需要连续片段、替换代价或多序列共同结果,必须另外定义问题,不能直接把两个输入的结论照搬过去。