Leetcode5:最长回文子串

题目地址:. - 力扣(LeetCode)

题目描述:

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

示例 1:

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

示例 2:

复制代码
输入:s = "cbbd"
输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

解题思路

这段代码是用来找出一个字符串中最长的回文子串。回文是一个正读和反读都相同的字符串。这个解决方案的核心思想是中心扩展法。它主要分为以下几个步骤:

  1. 边界条件 :如果字符串s为空或者长度小于2,那么直接返回s,因为单个字符或者空字符串本身就是一个回文。

  2. 初始化变量 :resIdx用来记录最长回文子串的起始索引,resLen用来记录最长回文子串的长度。

  3. 遍历字符串 :使用一个循环遍历字符串s中的每个字符(除了最后一个字符,因为最后一个字符单独不能形成回文)。

  4. 奇数长度回文 :对于每个索引idx,首先尝试找到以idx和idx+1为中点的最长奇数长度回文子串。这是通过longestLen方法实现的,该方法从中心向两边扩展,直到不满足回文条件。

  5. 偶数长度回文 :然后尝试找到以idx为中点的最长偶数长度回文子串。

  6. 更新结果 :如果找到的回文子串长度大于当前记录的最长长度resLen,则更新resLen和resIdx。

  7. 返回结果 :最后,使用substring方法根据resIdx和resLen截取最长回文子串并返回。

代码:

复制代码
class Solution {
    public String longestPalindrome(String s) {
        // 如果字符串为空或者只有一个字符,直接返回该字符串
        if (s == null || s.length() < 2) return s;
        
        int resIdx = 0, resLen = 1; // 初始化最长回文子串的起始索引和长度
        for (int idx = 0; idx < s.length() - 1; idx++) {
            // 尝试找到以当前字符为中心的最长奇数长度回文子串
            int len1 = longestLen(s, idx, idx);
            // 尝试找到以当前字符和下一个字符为中心的最长偶数长度回文子串
            int len2 = longestLen(s, idx, idx + 1);
            
            // 如果找到的奇数长度回文子串比当前记录的最长回文子串长,则更新结果
            if (len1 > resLen) {
                resLen = len1;
                resIdx = idx - resLen / 2;
            }
            // 如果找到的偶数长度回文子串比当前记录的最长回文子串长,则更新结果
            if (len2 > resLen) {
                resLen = len2;
                resIdx = idx - (resLen / 2 - 1);
            }
        }
        // 返回找到的最长回文子串
        return s.substring(resIdx, resIdx + resLen);
    }
    
    /**
     * 从给定的左右边界向左和右探索,找到最长的回文子串长度
     *
     * @param s 字符串
     * @param left 左边界索引
     * @param right 右边界索引
     * @return 最长回文子串的长度
     */
    private int longestLen(String s, int left, int right) {
        while (left >= 0 && right < s.length()) {
            // 如果左右边界对应的字符不相等,则跳出循环
            if (s.charAt(left) != s.charAt(right)) break;
            // 否则,向左和右扩展边界
            left--;
            right++;
        }
        // 返回找到的最长回文子串长度
        // right - left - 1 是因为while循环中left和right已经多减了1
        return right - left - 1;
    }
}

时间复杂度

时间复杂度是分析算法性能的一个重要指标,它描述了算法执行时间随输入规模增长的变化趋势。

  • 对于每个字符,我们最多会进行两次longestLen调用(一次是奇数长度回文,一次是偶数长度回文)。
  • 在longestLen方法中,最坏情况下会进行O(n)次迭代,其中n是字符串的长度。
  • 因此,总的时间复杂度是O(n^2),其中n是字符串的长度。

总结信息

这段代码实现了一个有效的算法来找出一个字符串中的最长回文子串。它使用了中心扩展法,这种方法的时间复杂度是O(n^2),其中n是字符串的长度。这种方法的优点是它不需要额外的存储空间来存储回文子串,因此空间复杂度是O(1)。此外,这种方法也很容易实现,并且对于大多数实际应用来说,其性能已经足够好。然而,对于非常大的字符串,可能需要更高效的算法,比如Manacher算法,它的时间复杂度可以达到O(n)

相关推荐
w_zero_one2 小时前
算法--模拟
java·数据结构·算法
秋天的怀念_David2 小时前
算法一千零一夜 · 第十三夜 幻方,武侠世界里的数学迷宫
java·程序人生·算法
秋天的怀念_David3 小时前
算法一千零一夜 · 第十四夜 幻方与奇妙的二进制
java·程序人生·算法
薛定e的猫咪3 小时前
(ICLR 2020)MAML 靠的不是快速学习,而是特征复用
人工智能·深度学习·学习·算法·机器学习
薛定e的猫咪3 小时前
(ICLR 2026)DF-META:面向 FJSP 的无导数元学习实例自适应调度
人工智能·深度学习·学习·算法·机器学习
小羊没烦恼!5 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#
wanderist.5 小时前
202609CSP认证P3
算法
云淡风轻~窗明几净6 小时前
角谷猜想最接近严格证明的测试 Version1.1.1
人工智能·算法·机器学习·图论
机器学习之心6 小时前
PINN × SVM × NSGA-II × 熵权TOPSIS:一套跑通「建模—优化—决策」的多目标优化框架
算法·机器学习·支持向量机
别动我齐刘海7 小时前
机器人 C++ / 系统联调补强2——异常处理、Protobuf
linux·c++·人工智能·学习·算法·机器学习·机器人