这一题思路上和前一题差不多,还是先对给定的有向图求出其中任意两点间的最短距离,然后考察字符串的变换方式。
但是,这里相较于上一题的难度在于说,这里的有向图的变换节点不再单纯是字母了,因此组合更多了。
其次的话,由于变换的节点为不定长的字符串,因此对source字符串和target字符串的变换关系可以给出不同的拆分关系,可以有不同的cost,需要对其选择最小值。
但是,即便如此,思路上来说还是很直接的,上半部分本质上和上一题一模一样,用一个Floyd算法就能直接得到。
而关于后半部分,事实上更加简单,直接使用动态规划就行。
不过,实际在处理过程中,遇到了超时的问题,因此这里做了一些剪枝的优化操作,这部分还是比较零碎的:
但即便给出上述这些多少繁琐的剪枝操作,还是仅仅勉强通过了所有测试样例,耗时依然非常长,不知道其他大佬们是怎么处理的,看了一两个大佬们的解法,不过没有看懂就是了,唉……
给出python代码实现如下:
class Trie:
def __init__(self):
self.trie = {}
def add_word(self, word):
trie = self.trie
for c in word:
trie = trie.setdefault(c, {})
trie["eos"] = ""
class Solution:
def minimumCost(self, source: str, target: str, original: List[str], changed: List[str], cost: List[int]) -> int:
n, m = len(source), len(original)
costs = defaultdict(lambda: math.inf)
for src, tgt, c in zip(original, changed, cost):
costs[(src, tgt)] = min(c, costs[(src, tgt)])
original = list(set(original))
changed_set = set(changed)
changed = list(changed_set)
interval = [src for src in original if src in changed_set]
for mid in interval:
for src in original:
for tgt in changed:
costs[(src, tgt)] = min(costs[(src, tgt)], costs[(src, mid)] + costs[(mid, tgt)])
trie = Trie()
for src in original:
trie.add_word(src)
@lru_cache(None)
def dp(idx):
if idx >= n:
return 0
ans = math.inf
_trie = trie.trie
src, tgt = "", ""
for j in range(idx, n):
src, tgt = src + source[j], tgt + target[j]
if src == tgt:
ans = min(ans, dp(j+1))
elif (src, tgt) in costs:
ans = min(ans, costs[(src, tgt)] + dp(j+1))
if source[j] not in _trie:
break
_trie = _trie[source[j]]
return ans
ans = dp(0)
return ans if ans != math.inf else -1
提交代码评测得到:耗时16432ms,占用内存30.3MB。