haskell 基础题解(36)

补为镜像串

【题目】镜像串也叫“回文串”,这种串是首尾对称的,也就是说,正读倒读都一样。
给你一个串,至少要添加多少个字母,才能成为镜像串呢?
比如: “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"

如果,首尾同,则问题变成中间的串的最小添加。
如果不同,有两种变成相同的方法,要分别考虑哪个更优。

另外,首尾同的情况下,如果仍在外层添加,是否会得到更优的解呢?这个可以去证明不可能更优。(此处略。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值