LeetCode:5. 最长回文子串

简介

题目链接:https://leetcode.cn/problems/longest-palindromic-substring/description/

解决方式:字符串 + 暴力枚举 / 中心扩展法(双指针)

暴力枚举

实现思路:

双重循环暴力枚举,枚举每一个可能的字符串,判断其是否是回文子串,是则进行下一步与全局维护的最大回文子串进行对比,实时更新最大回文子串。

java 复制代码
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        int maxLen = 0;
        int start = 0; // 记录最长回文子串的起始索引

        // 枚举所有子串的起始位置
        for (int i = 0; i < n; i++) {
            // 枚举所有子串的结束位置
            for (int j = i; j < n; j++) {
                if (isPalindrome(s, i, j)) {
                    int len = j - i + 1;
                    if (len > maxLen) {
                        maxLen = len;
                        start = i;
                    }
                }
            }
        }
        return s.substring(start, start + maxLen);
    }

    // 判断子串 s[i..j] 是否为回文串
    private boolean isPalindrome(String s, int left, int right) {
        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

中心扩展法

实现思路:

回文子串会有中心点,可能是一个(奇数)也可能是两个(偶数)。我们可以迭代所有可能的中心点,判断当前中心点是否是回文子串,然后由中心点周围扩展。同时维护一个全局最大回文子串,迭代的每一个回文子串都与全局最大进行对比,实时更新全局最大回文子串。

java 复制代码
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        // 全局最长回文子串(左闭右开)
        int maxLeft = 0;
        int maxRight = 0;
        // 迭代所有可能的中心点
        for(int center = 0; center < 2*n-1; center++){
            // 初始化双指针指向奇数或偶数中心
            int left = center / 2;
            int right = (center + 1) / 2;
            // 扩展回文子串,直到双指针指向回文子串边界的外侧
            while(left >= 0 && right < n && s.charAt(left) == s.charAt(right)){
                right++;
                left--;
            }
            // 比较该回文子串与全局最大回文子串
            if(right - left - 1 > maxRight - maxLeft){
                // 更新最大回文子串
                maxLeft = left + 1;
                maxRight = right;
            }
        }
        // 返回结果
        return s.substring(maxLeft, maxRight);
    }
}

另一种写法

java 复制代码
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        // 全局最长回文子串(左闭右开)
        int maxLeft = 0;
        int maxRight = 0;
        // 迭代所有可能的中心点
        for(int i = 0; i < n; i++){
            // 初始化双指针指向奇数中心
            int left = i;
            int right = i;
            // 扩展回文子串,直到双指针指向回文子串边界的外侧
            while(left >= 0 && right < n && s.charAt(left) == s.charAt(right)){
                right++;
                left--;
            }
            // 比较该回文子串与全局最大回文子串
            if(right - left - 1 > maxRight - maxLeft){
                // 更新最大回文子串
                maxLeft = left + 1;
                maxRight = right;
            }

            // 初始化双指针指向偶数中心
            left = i;
            right = i + 1;
            // 扩展回文子串,直到双指针指向回文子串边界的外侧
            while(left >= 0 && right < n && s.charAt(left) == s.charAt(right)){
                right++;
                left--;
            }
            // 比较该回文子串与全局最大回文子串
            if(right - left - 1 > maxRight - maxLeft){
                // 更新最大回文子串
                maxLeft = left + 1;
                maxRight = right;
            }
        }
        // 返回结果
        return s.substring(maxLeft, maxRight);
    }
}
相关推荐
小雉系统7 小时前
BcoreOS安全通信架构:FsSession 抗算法后门安全设计
算法·安全·架构
唐墨12311 小时前
linux kernel 比较数据大小的宏定义
linux·算法
拂拉氏12 小时前
【知识讲解-题目讲解】 统计满足K约束的子字符串数量2 (滑动窗口+前缀和+二分查找+分析)
算法·前缀和·二分查找·滑动窗口
lsc_blog15 小时前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
通信小呆呆16 小时前
电子战抗干扰技术:当“不被干扰”成为一种系统
算法·通信·mimo·isac
笑容掩饰我的失落16 小时前
区块链从小白到精通(八):从零实现一个标准 ERC-20 代币(完整可运行代码)
算法·区块链·php·智能合约·哈希算法
Severus_black17 小时前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl
2601_9679791219 小时前
机器学习必修课:经典算法与Python实战
python·算法·机器学习·实战·课程
程序猿打工仔20 小时前
计算机基础(C语言)考编、专技岗
c语言·开发语言·算法