diff算法_传统Diff算法为什么时间复杂度要O(n ^3)

81e708de94b97640cda0d660689ca3d3.png

原文链接:https://juejin.im/post/6892671384976097287

很多文章提到的都是新旧DOM树需要两两对比,但是没有说清楚为什么。

思考

  1. 大家想一下,如果让你来设计将一棵树转换为另一棵树,你会怎么设计?
  • 可能是直接暴力的根据index遍历比较,相同保留,不同就替换?

  • 也可能是用动态规划计算新旧两个节点变换所有情况的最小DOM操作次数?Min(新增,删除,替换)

    等等,我相信还有很多种可能。

    第一种非常粗暴,第二种是假设所有操作的优先级是相同的。第二种方案也就是我们传统的diff算法的核心方案,下面我们就此展开讨论

  1. 首先思考一个问题,创建一颗树的需要的复杂度是多少?

    很简单,因为树是一种递归的数据结构,需要递归的创建,复杂度O(n)。但是DOM的操作是非常耗性能的!

  2. 再思考一下,将一棵树转换为另一颗树,每个节点如何操作可以最少次数的操作DOM?

    太抽象了想不清楚没关系。下面我们来简化一下问题。

  3. 思考一下,将一个字符串转换为另一个字符串所需的最小操作次数,要如何计算?[wiki Edit distance][]

    题目还是理解的不是很清晰?看下面的示例![leetcode 72.编辑距离][leetcode 72.]

编辑距离

7e14c45f8804f2068e3ba248e5ca70c5.png

可能有部分同学已经想到了,直观的方式是用动态规划,通过这种记忆化搜索减少时间复杂度!

下面就展开介绍一下如何用动态规划解这道题

0588e0b68caddc5324a01b2703b555d0.png
bf7a004f8e93666ba802f20bbc6c64a1.png
代码
/**
 * @param {string} word1
 * @param {string} word2
 * @return {number}
 */
var minDistance = function(word1, word2) {
  //1.初始化
  let n = word1.length, m = word2.length
  let dp = new Array(n+1).fill(0).map(() => new Array(m+1).fill(0))
  for (let i = 0; i <= n; i++) {
      dp[i][0] = i
  }
  for (let j = 0; j <= m; j++) {
      dp[0][j] = j
  }
  //2.dp
  for(let i = 0; i <= n; i++) {
      for(let j = 0; j <= m; j++) {
          if(i*j) {
              dp[i][j] = word1[i-1] == word2[j-1] ? dp[i-1][j-1]: (Math.min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1)
          } else {
              dp[i][j] = i + j
          } console.log(dp[i][j])
      }
  }
  return dp[n][m]
};

得到字符串的最小编辑距离需要O(n^2)复杂度 -> 树的最小编辑距离需要O(n^3)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值