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

题目

给你一个字符串 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进厂的同学可以看看这个专栏:传送们
📣是个面试和考研的算法练习我们一起加油上岸之路
在这里插入图片描述

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥学

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值