首页 > 其他分享 >【字符串】-Lc5-最长回文子串(中心扩展法)

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

时间:2024-12-23 16:59:19浏览次数:5  
标签:子串 Lc5 end String int start 长度 回文

写在前面

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


目录


一、场景描述

  最长回文子串。给你一个字符串 s,找到 s 中最长的回文子串。
定义: 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

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

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

二、具体步骤

1.环境说明

名称说明
IntelliJ IDEA2023.2

2.代码

以下为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;
    }


}

写在后面

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

标签:子串,Lc5,end,String,int,start,长度,回文
From: https://blog.csdn.net/u010773514/article/details/144671260

相关文章

  • 【华为OD-E卷-最多提取子串数目 100分(python、java、c++、js、c)】
    【华为OD-E卷-最多提取子串数目100分(python、java、c++、js、c)】题目给定[a-z],26个英文字母小写字符串组成的字符串A和B,其中A可能存在重复字母,B不会存在重复字母,现从字符串A中按规则挑选一些字母,可以组成字符串B。挑选规则如下:同一个位置的字母只能挑选一次......
  • ACwing 1524. 最长回文子串
    ACwing1524.最长回文子串因为这个题的数据范围只有1000,所以能O(n)枚举,枚举回文子串的中点,然后向两边延展,看看极限长度是多少,注意每次要区分奇数长度字串和偶数长度字串,两种的计算方式不一样。#include<iostream>#include<cstdio>#include<cstdlib>intmain(){ std::s......
  • 回文链表
    给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。示例1:输入:head=[1,2,2,1]输出:true示例2:输入:head=[1,2]输出:false 思路:使用栈来存储节点值,然后开始比对/***Definitionforsingly-linkedlist.*str......
  • LeetCode题集-9 - 回文数
    题目:给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。01、反转字符串法此题我第一反应就是直接把整数转为字符串,然后通过字符串Reverse方法,反转字符串,最后......
  • 最小覆盖子串(滑动窗口)
    给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。   注意: 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。如果 s 中存在这样的......
  • 7-273 判断回文串
    若一个串正向看和反向看等价,则称做回文串。例如:t,abba,xyzyx均是回文串。给出一个长度不超过60的字符串,判断是否是回文串。输入格式:首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每行输入一个长度不超过60的字符串(串中不包含空格)。输出格式:对于每组测试数据,......
  • 代码随想录算法训练营第三十二天|动态规划理论基础|LC509.肥波那些数|LC70.爬楼梯|LC7
    动态规划理论基础    解释:动态规划,英文:DynamicProgramming,简称DP;如果某一问题有很多重叠子问题,使用动态规划是最有效的。动态规划五部曲:    1、确定dp数组(dptable)以及下标的含义;    2、确定递推公式;    3、dp数组如何初始化;   ......
  • string字符串比较/字符存取/插入和删除/子串获取
    示例:#include<iostream>usingnamespacestd;#include<string>#include<vector>#include<algorithm>//标准算法的头文件//字符串比较voidtest01(){stringstr1="xello";stringstr2="hello";if(str1.compare(s......
  • 5. 最长回文子串
    题目链接解题思路:最长回文子串问题,首先要将原字符串扩充,比如abba,暴力是以每个字符s[i],左右两边扩,如果是abba,得不到最优解,扩充成#a#b#b#a#,就不会有问题,最优解是manacher算法。假设s[i]扩充的区域是[x,y],是目前便利到的,最远的距离,我们称i为回文中心C,y为回文最远右边界R,同时,......
  • 代码随想录算法训练营第四十六天|leetcode647. 回文子串、leetcode516.最长回文子序列
    1leetcode647.回文子串题目链接:647.回文子串-力扣(LeetCode)文章链接:代码随想录视频链接:动态规划,字符串性质决定了DP数组的定义|LeetCode:647.回文子串哔哩哔哩bilibili思路:嘿,看不懂有一点,看解析吧1.1视频后的方法其实看完视频以后,感觉这个题目真的不难,我想到了二维......