看起来这可以使用Dynamic Programming解决。在不失一般性的情况下,我可以将问题重新表述为:
给定搜索空间S = {s1, s2, ..., sn}
,一个针对(si, sj)
,我们必须找到(k, l)
这样的位置对:
(sk, sl) == (si, sj)
distance(k, l)
是最小值。
可以通过以下方式制定该问题的递归解决方案:
Cost(m) =
LARGEST_NUMBER, if m = 0
Min (Cost(m-1), distance(S[m], Latest_si)), if m > 0 and S[m] == sj
Min (Cost(m-1), distance(S[m], Latest_sj)), if m > 0 and S[m] == si
Cost(m-1), if m > 0 and S[m] != (si, sj)
在哪里,
Cost(m)
是优化函数。(si, sj)
它表示搜索空间中的最小距离S[1:m]
。
Latest_si
是 的最新位置si
。
Latest_sj
是 的最新位置sj
。
这可以转换为空间复杂度为to store的O(n)
自下而上循环。O(n)
Cost
这是上述算法在 Python 中的实现:
def min_phrase (S, si, sj):
Cost = []
for i in S:
Cost.append([len(S), [-1, -1]])
latest_si = -1
latest_sj = -1
for idx, v in enumerate(S):
if v == si:
if latest_sj >=0:
cost = idx - latest_sj
if cost < Cost[idx - 1][0]:
Cost[idx] = [cost, [latest_sj, idx]]
else:
Cost[idx] = Cost[idx - 1]
else:
Cost[idx] = Cost[idx - 1]
latest_si = idx
elif v == sj:
if latest_si >=0:
cost = idx - latest_si
if cost < Cost[idx - 1][0]:
Cost[idx] = [cost, [latest_si, idx]]
else:
Cost[idx] = Cost[idx - 1]
else:
Cost[idx] = Cost[idx - 1]
latest_sj = idx
else:
Cost[idx] = Cost[idx - 1]
return Cost[len(S) - 1]
if __name__ == '__main__':
S = ("one", "two", "three", "four", "five", "four", "six", "one")
si = "one"
sj = "four"
result = min_phrase(S, si, sj)
if result[1][0] == -1 or result[1][1] == -1:
print "No solution found"
else:
print "Cost: {0}".format(result[0])
print "Phrase: {0}".format(" ".join(S[result[1][0] : result[1][1] + 1]))