首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

LeetCode 5:最長回文子串暴力解法與優化分析

     編輯:Java 綜合教學

LeetCode 5:最長回文子串暴力解法與優化分析

給定字符串 S(長度 ≤ 1000),找出最長回文子串。本文展示暴力枚舉解法(會超時),並指明優化方向。

暴力解法代碼

public class Solution {
    public String longestPalindrome(String s) {
        if (s.length() <= 1) return s;
        
        String longest = "";
        int maxLen = 0;
        char[] chars = s.toCharArray();
        
        for (int i = 0; i < chars.length; i++) {
            // 剪枝:剩餘長度不足以超過當前最長
            if (chars.length - i + 1 <= maxLen) return longest;
            
            for (int j = chars.length - 1; j > i; j--) {
                if (chars[i] == chars[j]) {
                    String sub = s.substring(i, j + 1);
                    int len = j - i + 1;
                    if (isPalindrome(sub) && len > maxLen) {
                        longest = sub;
                        maxLen = len;
                        break; // 同起點只需最長回文
                    }
                }
            }
        }
        return longest;
    }
    
    private boolean isPalindrome(String str) {
        char[] c = str.toCharArray();
        int i = 0, j = c.length - 1;
        while (i <= j) {
            if (c[i] != c[j]) return false;
            i++; j--;
        }
        return true;
    }
}

複雜度瓶頸

  • 時間:O(n³) — 雙重循環 O(n²) × 回文驗證 O(n)
  • 空間:O(1) — 僅常數額外空間

n=1000 時約 10⁹ 次操作,必超時。

主流優化方案

算法時間空間核心思想
中心擴展法O(n²)O(1)以每字符/字符間隙為中心向兩側擴展
動態規劃O(n²)O(n²)dp[i][j] 記錄子串是否回文
Manacher 算法O(n)O(n)利用回文對稱性避免重複計算

中心擴展法參考實現

public String longestPalindrome(String s) {
    if (s == null || s.length() < 2) return s;
    int start = 0, end = 0;
    for (int i = 0; i < s.length(); i++) {
        int len1 = expand(s, i, i);     // 奇數長度
        int len2 = expand(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(start, end + 1);
}

private int expand(String s, int left, int right) {
    while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
        left--; right++;
    }
    return right - left - 1;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved