3213. Construct String with Minimum Cost
Read the full problem statement on LeetCode.
Difficulty: hard Acceptance: 19% Topics: Array, String, Dynamic Programming, Suffix Array
View full problem on LeetCode Reading material
Reference solution (spoiler · python)
# Time: O(n^2 + w * l)
# Space: O(t)
import itertools
# trie, dp
class Solution(object):
def minimumCost(self, target, words, costs):
"""
:type target: str
:type words: List[str]
:type costs: List[int]
:rtype: int
"""
INF = float("inf")
def query(i):
curr = trie
for j in xrange(i, len(target)):
x = target[j]
if x not in curr:
break
curr = curr[x]
if "_end" in curr:
dp[j+1] = min(dp[j+1], dp[i]+curr["_end"])
_trie = lambda: collections.defaultdict(_trie)
trie = _trie()
for w, c in itertools.izip(words, costs):
node = reduce(dict.__getitem__, w, trie)
if "_end" not in node:
node["_end"] = INF
node["_end"] = min(node["_end"], c)
dp = [INF]*(len(target)+1)
dp[0] = 0
for i in xrange(len(target)):
if dp[i] == INF:
continue
query(i)
return dp[-1] if dp[-1] != INF else -1
# Time: O(n^2 + w * l)
# Space: O(t)
import itertools
# trie, dp
class Solution2(object):
def minimumCost(self, target, words, costs):
"""
:type target: str
:type words: List[str]
:type costs: List[int]
:rtype: int
"""
INF = float("inf")
class Trie(object):
def __init__(self):
self.__nodes = []
self.__mns = []
self.__new_node()
def __new_node(self):
self.__nodes.append([-1]*26)
self.__mns.append(INF)
return len(self.__nodes)-1
def add(self, w, c):
curr = 0
for x in w:
x = ord(x)-ord('a')
if self.__nodes[curr][x] == -1:
self.__nodes[curr][x] = self.__new_node()
curr = self.__nodes[curr][x]
self.__mns[curr] = min(self.__mns[curr], c)
def query(self, i):
curr = 0
for j in xrange(i, len(target)):
x = ord(target[j])-ord('a')
if self.__nodes[curr][x] == -1:
break
curr = self.__nodes[curr][x]
if self.__mns[curr] != INF:
dp[j+1] = min(dp[j+1], dp[i]+self.__mns[curr])
trie = Trie()
for w, c in itertools.izip(words, costs):
trie.add(w, c)
dp = [INF]*(len(target)+1)
dp[0] = 0
for i in xrange(len(target)):
if dp[i] == INF:
continue
trie.query(i)
return dp[-1] if dp[-1] != INF else -1
Solution from kamyu104/LeetCode-Solutions · MIT