⚡考研面试⚡算法每天练——最长回文子串

Posted 肥学大师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⚡考研面试⚡算法每天练——最长回文子串相关的知识,希望对你有一定的参考价值。

题目

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:

输入:s = "cbbd"
输出:"bb"
示例 3:

输入:s = "a"
输出:"a"
示例 4:

输入:s = "ac"
输出:"a"
提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
通过次数666,680提交次数1,909,975

一点点思路

看过我的这个系列的同学应该知道我在这块主要就是和大家说说我的想法,看到这道题我首先想到了之前讲的,无重复字符的最长子串当时用滑动窗口解决的已经忘了的小伙伴可以回去看看。
但是在今天的这题明显用不到啊,我刚开始的思路很简单大家都做过判断回文数的那道题吧!然后将每个子串进行判断找出最大的,这种暴力枚举的方法。我看了一下要求1 <= s.length <= 1000数值还是可以的。所以暴力枚举可能会超时。我是说可能我没去试试,大家有兴趣可以试试

不要说我懒可以吗。可能也是不会,所以这题到底用什么方法解呢?请看下面讲解。

正式开撸

判断回文串

无论哪一种方法都要判断是否是回文串所以我们先说说这个。什么是回文串我就不说了这个不会自己百度。
判断方法一:

如图如果i指向的字符等于j指向的字符继续将两指针内移接着判断,有一对不符合就不是,这是对奇数个字符的情况同样偶数也是这样。

判断方法二:

如果是奇数我们就从中间一个字符开始,如果是偶数就从中间两个字符开始判断ij的位置上的字符是否相等不相等就不是。
这两种方法大家可以根据自己的思路自己尝试写一下试试。

我的解题方法

受到第二种判断方法的启发,找到了一种解法叫中心扩散法这个判断思路差不多即,边界情况即为子串长度为 1 或 2 的情况。我们枚举每一种边界情况,并从对应的子串开始不断地向两边扩展。如果两边的字母相同,我们就可以继续扩展,例如从 P(i+1,j-1)P(i+1,j−1) 扩展到 P(i,j)P(i,j);如果两边的字母不同,我们就可以停止扩展,因为在这之后的子串都不能是回文串了。
先写出来判断方法:

public int expandAroundCenter(String s, int left, int right) {
		//判断边界问题还有上面讲的i和j(这里是left和right)位置的字符是否相等不满足这些条件的一个就直接跳出循环了
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            --left;
            ++right;
        }
        return right - left - 1;
    }

来看主函数

public String longestPalindrome(String s) {
		//这个主要是运气牌,一般不会给你一个字符的测试的,当然我们还是需要谨慎一些
        if (s == null || s.length() < 1) {
            return ;
        }
        int fei = 0, xue = 0;
        //从串的第一个元素为中心扩散
        for (int i = 0; i < s.length(); i++) {
            //以奇数子串为前提开始
            int len1 = expandAroundCenter(s, i, i);
            //以偶数子串为前提
            int len2 = expandAroundCenter(s, i, i + 1);
            //比较两者谁更大
            int len = Math.max(len1, len2);
            //找到新的最大回文串的位置
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        //返回这个串
        return s.substring(fei, end + 1);
    }

关于这个方法:

substring(int beginIndex, int endIndex)

我们简单测试一下用处以免有大佬不知道,也可用我上次说的方法试试详细了解一下。

public static void main(String[] args) {
		String a="sfjls";
		System.out.println(a.substring(2,4));
		System.out.println(a.substring(2));
		
	}
结果
jl
jls

大家感受一下吧,好的今天的算法题就到这里了我们明天再见。

🎃特别介绍:

📣小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶
📣有什么不明白的欢迎私信或留言,得到细致讲解。另外想要进阶的朋友可以关注练手项目专栏

📣另外想学JavaWeb进厂的同学可以看看这个专栏:传送们
📣是个面试和考研的算法练习我们一起加油上岸之路

以上是关于⚡考研面试⚡算法每天练——最长回文子串的主要内容,如果未能解决你的问题,请参考以下文章

编程之法:面试和算法心得(最长回文子串)

LeetCode高频算法面试题 最长回文子串

《算法竞赛入门经典》3.3最长回文子串

⚡考研面试⚡算法每天练——三数之和(中心扩散法)

算法-最长回文子串(Manacher算法)

数据结构与算法 Manacher 算法求最长回文子串