leetcode解题报告5. Longest Palindromic Substring

leetcode解题报告5. Longest Palindromic Substring

题目地址

难度是medium

题目描述

回文串:当一个字符串从左到右,和从右到左是一样的的时候,称为回文串
题目要求,给定一个字符串,找出它的子串里面最长的回文串

我的思路

第一个思路:首先最直观的思路是暴力求解,遍历所有子串,判断是否是回文串,在选择最长的那个就行了。简单可行,但肯定超时

第二个思路:通过窗口移动来遍历子串,窗口大小从大到小,那么这样找到第一个子串如果是回文串,那肯定是最长回文串了,不用全部遍历。但这只是比暴力方法稍微好一点,当最长回文串长的时候,优化明显,但当最长回文串短时,几乎和暴力方法无异。我尝试实现,并提交,果然结果超时。当多提交几次,发现有时又能AC,可能这个办法超时不是很严重。

第三个思路:根据回文串的特点,可以通过选定一个位置,然后左右延拓的办法来遍历子串。遍历奇数长度的子串,对某个位置的字符为中心,第一个子串是中心本身,左右长度加一,遇到不是回文串时(或超过字符串范围时),结束以该中心的子串寻找。选择下一个中心,继续。遍历偶数长度的子串类似,只是以某两个相邻的字符为中心。这方法相比暴力少遍历很多子串。利用回文串的特点,当一个子串不是回文串时,那么它左右延拓得到的字符串也肯定不是回文串。我们就能跳过遍历这些回文串。而且判断某个子串是否回文串时,我们只是判断左右延拓的字符是否相等而已,相比暴力遍历时要好很多。

我的代码

class Solution {
public:
    string longestPalindrome(string s) {
        string ans;
        int max = 0;
        int len;
        //遍历奇数长度的子串
        for (int i = 0; i < s.size(); i++) {
            len = 1;
            int a = i - 1;
            int b = i + 1;
            while (a >= 0 && b < s.size()) {
                if (s[a] != s[b]) {
                    break;
                }
                a--;
                b++;
                len += 2;
            }
            if (len > max) {
                ans = s.substr(a+1, len);
                max = len;
            }
        }
        //遍历偶数长度的子串
        for (int i = 0; i < s.size(); i++) {
            len = 0;
            int a = i;
            int b = i+1;
            while (a >= 0 && b < s.size()) {
                if (s[a] != s[b]) {
                    break;
                }
                a--;
                b++;
                len += 2;
            }
            if (len > max) {
                ans = s.substr(a+1, len);
                max = len;
            }
        }

        return ans;
    }
};

阅读官方题解

题目地址

情况总结如下,具体看官方题解

第一个办法是比较粗糙的。具体是找原字符串和它逆序字符串之间的公共子串。这个公共子串是回文串的一个超集,所以还得判断是否是回文串。

第二个办法,暴力遍历,超时,没什么可说的

第三个办法是动态规范。比较直观。

第四个办法就是和我的第三个思路是一致的。

第五个办法是Manacher’s algorithm。比较复杂。

思想核心总结

对于字符串问题,最直观的思路是暴力遍历。但这一般是不好的。我们希望不是简单地遍历,而是能利用问题的特性和后面遍历能利用到前面遍历的信息,避免不必要的遍历,从而加速。

一般来说,暴力遍历的下一步思路是考虑动态规划或窗口移动等方法,加速遍历。

在有些时候,更应该利用题目的特性来优化,比如本题目的回文串的特点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值