补为镜像串
【题目】镜像串也叫“回文串”,这种串是首尾对称的,也就是说,正读倒读都一样。
给你一个串,至少要添加多少个字母,才能成为镜像串呢?
比如: “abb” 需要添一个。“ababcabc” 则需要添3个。
(注意,可以任意位置添字母,不局限于首尾)
这个问题初看起来没什么头绪,因为哪都能添,太灵活,可能性太多。但如果用递归的思考方法就会另一番景象了。
考虑一个镜像串的首尾字母必然是相同的。如果不同,那么无论如何都必须在首或尾添一个。这步是绕不过去的。那我们何不就先做这步?然后呢? 剩下的那个串如果知道最少要加多少,那问题不就是它说的数再加1吗?
上个代码:
toMirror :: String -> Int
toMirror "" = 0
toMirror [_] = 0
toMirror s | head s == last s = toMirror . init . tail $ s
| otherwise =
let n1 = toMirror (tail s)
n2 = toMirror (init s)
in min n1 n2 + 1
main :: IO ()
main = do
print $ toMirror "abc"
print $ toMirror "aba"
print $ toMirror "abb"
print $ toMirror "abababc"
print $ toMirror "ababcabc"
如果,首尾同,则问题变成中间的串的最小添加。
如果不同,有两种变成相同的方法,要分别考虑哪个更优。
另外,首尾同的情况下,如果仍在外层添加,是否会得到更优的解呢?这个可以去证明不可能更优。(此处略。。。)