[50](移動規則)最長の回文部分文字列(LC 5)

最長の回文部分文字列

問題の説明

文字列sを指定し、sで最長の回文部分文字列を見つけます。

問題解決のアイデア

以前のこの質問と同様の質問:最長の回文サブシーケンス

違いは、質問が最長の回文サブシーケンスの長さを返すのに対し、この質問は最長の回文サブストリングを返すことです。つまり、戻り値は文字列型です。

戻り値は異なりますが、要件は同じであるため、動的計画法を使用してこの問題を解決することもできます:

部分文字列の場合、それが回文であり、長さが2より大きい場合、最初と最後の2文字を削除した後でも、それは回文のままです。dp(i、j)を使用して、文字列sのi番目の文字で構成される文字列が回文であるかどうかを示します。s[i、j]が回文である場合、s [i] == s [j] 、および両端を削除した後の部分文字列は、まだ回文です。したがって、状態遷移方程式を記述します。

dp(i、j)==(s [i-1] == s [j + 1])&& dp(i + 1、j-1)

次に、最長の回文部分文字列は、dp [i] [j]が真であり、j-i +1が最長の文字列です。

コード:

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        String res = "";
        for (int l = 0; l < n; ++l) {
    
    //l表示回文串的长度-1
            for (int i = 0; i + l < n; ++i) {
    
    //i为子串起点
                int j = i + l;//j为子串终点
                if (l == 0) {
    
    //此为 i == j 的情况
                    dp[i][j] = true;
                } else if (l == 1) {
    
     //此为回文串只有两个字符的情况,需要两个字符相等才能为真
                    dp[i][j] = (s.charAt(i) == s.charAt(j));
                } else {
    
    //推导出的状态转移方程
                    dp[i][j] = (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]);
                }
                if (dp[i][j] && l + 1 > res.length()) {
    
     //求最长串
                    res = s.substring(i, i + l + 1);
                }
            }
        }
        return res;
    }
}

時間計算量:O(n ^ 2)
空間計算量:O(n ^ 2)

解決策2:

このソリューションは、文字列の各文字をトラバースし、それを回文の中心として使用するという考え方も提供します。中心が左側と右側に等しい場合は、拡大を続けます。等しくない場合は、トラバースを続けます。次のキャラクター。

イラスト:出典

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
コード:

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        if (s == null || s.length() < 1) {
    
    
            return "";
        }
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++) {
    
    
            int len1 = expandAroundCenter(s, i, i);
            int len2 = expandAroundCenter(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);
    }

    public int expandAroundCenter(String s, int left, int right) {
    
    
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
    
    
            --left;
            ++right;
        }
        return right - left - 1;
    }
}


链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/
来源:力扣(LeetCode)

おすすめ

転載: blog.csdn.net/qq_43424037/article/details/114692812
おすすめ