Advertisement
goodwish

Hard 623. K Edit Distance

Nov 2nd, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.56 KB | None | 0 0
  1. #meat
  2. Q: 找多个单词和 target 单词的编辑路径, 距离小于 k 的单词们.
  3.  
  4. 思路: 用 Trie 存放重复的路径, DFS, 其余和 Edit Distance 一样.
  5. 类似 preorder 根须遍历. 先访问根节点, 再访问子节点.
  6. DFS 是单线程, 一条公共路径的子节点走完以后, 才会去下一条公共路径.
  7. 不用担心数据重用之前被修改.
  8.  
  9. 递归定义: dfs(c, root, i, t, k, f, res):
  10.  
  11. 递归拆解:
  12. 每层调用, 只比较一个字母, 即当前节点的字母.
  13.  
  14. - 递推方程:
  15. for j in range(len(t)):
  16.  upd = f[i - 1][j - 1] + 1
  17.  if c == t[j - 1]: upd -= 1
  18.  f[i][j] = min(f[i-1][j] + 1, f[i][j - 1] + 1, upd)
  19.  
  20. - 找到一个编辑距离小于 k 的单词, 加进结果集.
  21. root.is_word and f[i][n] <= k:
  22.  
  23. - 计算出 f[i][j] 以后, 遍历每个子节点.
  24. for c1 in root.child:
  25.   self.dfs(c1, root.child[c1], i + 1, t, k, f, res)
  26.  
  27. 数据结构:
  28. class TrieNode:
  29. f = [[float("inf")] * (n + 1) for _ in range(m + 1)]
  30.  
  31. note.
  32. if j - 1 >= 0 and c == t[j - 1]: # 注意下标索引越界.
  33. .
  34.  
  35. class TrieNode:
  36.     def __init__(self,):
  37.         self.child = {}
  38.         self.is_word = False
  39.         self.word = ""
  40.  
  41. class Solution:
  42.     def kDistance(self, words, target, k):
  43.         # init
  44.         self.root = TrieNode()
  45.         n = len(target)
  46.         m = 0
  47.         for w in words:
  48.             if len(w) - n > k:
  49.                 continue
  50.             m = max(m, len(w))
  51.             self.insert(w)
  52.        
  53.         f = [[float("inf")] * (n + 1) for _ in range(m + 1)]
  54.         for i in range(m + 1):
  55.             f[i][0] = i
  56.         for i in range(n + 1):
  57.             f[0][i] = i
  58.         res = []
  59.         self.dfs("", self.root, 0, target, k, f, res)
  60.         return res
  61.    
  62.     def dfs(self, c, root, i, t, k, f, res):
  63.         n = len(t)
  64.         if i > 0:
  65.             for j in range(n + 1):
  66.                 f[i][j] = min(f[i-1][j], f[i][j - 1], f[i-1][j-1]) + 1
  67.                 if j - 1 >= 0 and c == t[j - 1]:
  68.                     f[i][j] = min(f[i][j], f[i - 1][j - 1])
  69.         if root.is_word:
  70.             if f[i][n] <= k:
  71.                 res.append(root.word)
  72.         for c1 in root.child:
  73.             self.dfs(c1, root.child[c1], i + 1, t, k, f, res)
  74.    
  75.     def insert(self, word):
  76.         root = self.root
  77.         for c in word:
  78.             if c not in root.child:
  79.                 root.child[c] = TrieNode()
  80.             root = root.child[c]
  81.         root.is_word = True
  82.         root.word = word
  83.  
  84. ["acc","abcd","ade","abbcd","ddeeff","fabcd","fabcde"]
  85. "abc"
  86. 2
  87. Output:
  88. ["abbcd","abcd","acc","ade","fabcd"]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement