LeetCode-5-最长回文子串

这道题其实每次看题目列表都会看到,然后还每次似懂非懂,也看了很多次解法了,但是就是看一次忘一次。

今天趁着明天周末可以不用早起,准备写一两道,又看到了这道题,尝试按照记忆写一写。

题目

最长回文子串
最长回文子串
这里需要注意的是子串,而不是子序列,子串必须是连续的,子序列没有要求连续(516. 最长回文子序列

解法
  1. 暴力解法:
    所谓暴力,无非就是穷举,然后判断每个子串是否是回文,然后和记录的长度做比较,判断是否更新。
    首先就要穷举出所有子串:双循环,外层表示子串的起点位置,内层表示子串的终点位置。
fun longestPalindrome(s: String): String {
        if(s.length<2) return s
        var maxLen=0
        var start=0
        for (i in 0 until s.length){
            for(j in i until s.length){
                if(check(s,i,j)&&j-i+1>maxLen){
                    maxLen=j-i+1
                    start=i
                }
            }
        }
        return s.substring(start,start+maxLen)
    }
    private fun check(s:String, i:Int, j:Int):Boolean{
        var start=i
        var end=j
        while(start<=end){
            if(s[start]!=s[end])
                return false
            start++
            end--
        }
        return true
    }

提交结果
哈哈,执行耗时可知速度是真的慢

  1. 中心扩散法
    暴力解法判断一个子串需要两次遍历确定每个子串,再去判断,耗时的主要原因就在这。
    中心扩散法是采用反向的思维,先确定回文中心,再求得以此中心的最长回文子串长度。
fun longestPalindrome(s: String): String {
        if(s.length<2) return s
        var end=0
        var start=0
        for (i in 0 until s.length){
            val len=Math.max(getLen(s,i,i),getLen(s,i,i+1))
            if(len>end-start) {
                end = i+len/2 
                start = i-(len-1)/2
            }
        }
        return s.substring(start,end+1)
    }

    /**
     * start end中间字母数量
     * 实际长度是 返回值+1
     * 减一是为了好统一处理奇数个数和偶数个数
     */
    private fun getLen(s:String, i:Int, j:Int):Int{
        var start=i
        var end=j
        while(start>=0&&end<s.length){
            if(s[start]!=s[end])
                return end-start-1
            start--
            end++
        }
        return end-start-1
    }

提交结果
果然快多了。。。
注意点:
getLen返回的end-start-1/
一般情况下如果是中心单数对称如aba,那么
start=i+len/2
end=i-len/2
这时候len是实际长度还是长度-1,实际上没区别(3/2==2/2)

如果是双数对称如abba,这个时候i指向第一个b,所以start是靠左的,计算起始位置要少减一位
这时候如果len是实际长度:
end=i+len/2
start=i-len/2+1

所以通过返回长度-1的方式消除这两种情况的差异

  1. 马拉车算法
    待续。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值