引言

在前文中,已经利用分治思想,将原本需要O(mn)空间复杂度的动态规划问题转换成只需要O(m+n),进一步地,在本文中,我们考虑能否将时间复杂度也降低。最终实现的结果是将O(mn)的时间复杂度降低到O(αmax{m,n})。

减少冗余计算

问题分析

考虑如果两个需要对齐的字符串很不相似(例如“gold”,“time”),我们是否还有必要用动态规划的方式对其计算相似度?设计动态规划对齐两个字符串的目的(我们从应用出发),如修正用户的错误输入,对比文章是否抄袭,这些都建立在两者较为相似的情况下(这个较为相似的标准由使用者制定)。因此,我们可以对那些很多字符对不上的字符串做一个预处理,直接在这个阶段停止,减少没必要的计算,而相似度较高的两个字符串体现在动态规划中有什么特点?

动态规划-序列联配问题(3)减少冗余计算
箭头的方向:

  • 向上的箭头:S用空格与T中字符对齐
  • 向左的箭头:T用空格与S中字符对齐
  • 斜向上的箭头:S与T中字符与字符对齐(可能相等&不等)

可以发现像左下角-30这样的犄角旮旯,根本不会影响到最终路径的结果,预处理去掉很不相似的单词,可以保证最终的路径应该在对角线附近,所以我们真正需要计算的是对角线附近的区域。

解决思路

通过设置一个参数α在原数组上开出一个条偏离带,如下图:
动态规划-序列联配问题(3)减少冗余计算
在原动态数组中即如下:
动态规划-序列联配问题(3)减少冗余计算

伪代码对比

原伪代码采用双重for循环,将每一个格子的结果计算出来,进行了太多不必要冗余计算,如下:
动态规划-序列联配问题(3)减少冗余计算
设置了α之后伪代码如下:
动态规划-序列联配问题(3)减少冗余计算
将不足条带α长度的部分补全,可以发现总的计算格子数量不大αmax{m,n}新的时间复杂度是O(αmax{m,n})。

总结

通常我们降低算法运行时间复杂度办法是减少冗余计算,我们通过观察回溯路径,发现我们真正要考虑的是那些相似度较高的情况,对于一些差异较大的,我们直接在预处理部分就可以去掉。因此我们发现这类结果路径通常位于对角线附近,这就发现侧边角的结果实际上是冗余计算。为了避免,设计了步骤如下:

  1. 将可能区域用条带包裹起来,这个条带的表现就是参数α
  2. 对数组对重新定义计算方式(BANDED−DP(T,S,α)),多考虑了一层其是否在条带内的因素,这里减少了冗余计算

从序列联对的案例可以看出,为了减少实际使用过程的时间复杂度,我们可以通过结合应用将所有可能案例进行拆分,对于明显不成立的情况,可以在预处理阶段进行筛除,为后续降低时间复杂度提供基础。

相关文章:

  • 2021-06-05
  • 2022-12-23
  • 2021-04-12
  • 2022-12-23
  • 2021-04-22
  • 2021-06-03
  • 2022-12-23
  • 2021-10-02
猜你喜欢
  • 2021-06-25
  • 2021-07-15
  • 2021-12-29
  • 2021-07-06
  • 2021-09-27
  • 2021-08-07
  • 2022-12-23
相关资源
相似解决方案