【字符串】-Lc5-最长回文子串(中心扩展法)

写在前面

最近想复习一下数据结构与算法相关的内容,找一些题来做一做。如有更好思路,欢迎指正。


目录


一、场景描述

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

定义: 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

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

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

二、具体步骤

1.环境说明

名称 说明
IntelliJ IDEA 2023.2

2.代码

以下为Java版本实现:

java 复制代码
public class Lc5_longestPalindrome {

    public static void main(String[] args) {
        // String s = "babad";
        String s = "cbbd";
        System.out.println(longestPalindrome(s));
    }

    /**
     * 思想:
     * 返回值是String
     *
     * 整体思路是从给的字符串中找到 2 个位置 start、end,然后从s.subString(start, end + 1)截取获得
     * 迭代的条件是,每次的返回回文子串的长度,如果比当前大,start和end就向2遍扩展
     *
     * 剩下的问题就是如何得到回文字串?
     * 思路是由中间向两边扩展(中心扩展法)
     *
     * 说明:
     * 回文中心,有 2 种方式
     *
     * 奇数长度回文:回文中心是1个字符,初始化 l = r =i,  得到的回文长度是奇数,1/3/5
     * 偶数长度回文:回文中心是2个字符,初始话 l=i, r=i+1,得到的回文长度是偶数,0/2/4
     *
     * for循环,i取值到 i < length - 1 即可 (最后一个数就不需要循环了)
     * 2种方式,由回文中心向两边扩展(lr双指针)
     *
     * 由中心向两边扩展,返回的是回文字串的长度
     * 计算2种方式的最大值与原有长度比较,如果大,则覆盖start和end
     */
    private static String longestPalindrome(String s) {
        int start = 0, end = 0;
        // 寻找回文中心
        for (int i = 0; i < s.length() - 1; i++) {
            // 回文中心是1个字符
            int oddLen = expandAroundCenter(s, i, i);
            // 回文中心是2个字符
            int evenLen = expandAroundCenter(s, i, i + 1);
            int len = Math.max(oddLen, evenLen);
            // 计算新的长度是否大于已存在的回文长度
            if (len >= end - start + 1) {
                /**
                 * 注意:回文中心是2个字符,回文长度是偶数时,计算start时,需要先把 len - 1,
                 *
                 * 示例:
                 * 索引        01 2345 6
                 * 字符串      ab dccd e
                 *
                 * 当 i = 3 时,回文中心是 cc,找到的回文字符串是 dccd
                 * start = 3 - (4 - 1) / 2 = 2
                 *       ≠ 3 - 4/2 = 1
                 */
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }

        return s.substring(start, end + 1);
    }

    /**
     * 中心扩展法
     * 以传入的参数为中心,向两边扩展,返回回文串的长度
     *
     * 数组求长度
     *  -101234
     *    babad
     * aba = (2 - 1) + 1 = 3
     *
     * @param s
     * @param left
     * @param right
     * @return
     */
    private static int expandAroundCenter(String s, int left, int right) {
        int l = left, r = right;
        for (; l >= 0 && r < s.length(); l--, r++) {
            if (s.charAt(l) != s.charAt(r)) {
                break;
            }
        }
        // 循环跳出时的l和r是不满足条件的(字符不相等 或者 超界),所以在计算时,有效的回文字符长度索引是 l + 1, r -1,
        // 数组通过索引求长度,需要再 +1
        // (r - 1) - (l + 1) + 1 = r - l - 1
        return r - l - 1;
    }


}

写在后面

如果本文内容对您有价值或者有启发的话,欢迎点赞、关注、评论和转发。您的反馈和陪伴将促进我们共同进步和成长。

相关推荐
vx_BS8133017 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683617 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
yyy(十一月限定版)30 分钟前
寒假集训4——二分排序
算法
星火开发设计31 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
醉颜凉41 分钟前
【LeetCode】打家劫舍III
c语言·算法·leetcode·树 深度优先搜索·动态规划 二叉树
达文汐44 分钟前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
一匹电信狗44 分钟前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
User_芊芊君子44 分钟前
【LeetCode经典题解】搞定二叉树最近公共祖先:递归法+栈存路径法,附代码实现
算法·leetcode·职场和发展
培风图南以星河揽胜1 小时前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
算法_小学生1 小时前
LeetCode 热题 100(分享最简单易懂的Python代码!)
python·算法·leetcode