leetcode 5. 最長の回文部分文字列 (C++)

トピック

ここに画像の説明を挿入します

アイデア分析

  1. 中心を両側に拡張するという考え方は、回文文字列の性質に基づいています。たとえばstr = "aba"bから開始して両側に同時にトラバースし、文字が同じかどうかを比較します。 としましょう , ,left = i - 1そしてright = i + 1、逐次比較が確立されます。str[left] == str[right]成立した場合は比較を継続し、成立しない場合はこの繰り返しを終了してi ++次の比較を実行します。このメソッドの最大時間計算量は ですO(n^2)
  2. この方法は、動的計画法の考え方に基づいて、小さいものから大きいもの、短いものから長いものまで回文文字列であるかどうかを判定します(単一文字の場合、デフォルトで回文文字列、つまり長さが決まります)。プロパティは、配列を初期化するための条件1としても使用されます(から までの添え字の部分)、つまり)。その後のすべての判断はこれに基づいて行われます。たとえば、回文文字列またはを判定する場合、それが真かどうかを判定するだけでよく、真であれば 、そうでなければ となりますもちろん、詳細な問題があります。コードの実装を参照してください。dpdp[i][j]ijdp[i][j]=truedp[i][i + len - 1]truefalses[i] == s[i + len - 1]dp[i][i + len - 1] = dp[i + 1][i + len - 2] dp[i][i + len - 1] = false

解決策 1

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        int left, right;
        string max_str = "", cur_str = "";
        for(int i = 0;i < s.length(); ++i){
    
    
            left = i - 1, right = i + 1;
            cur_str = s[i];
            for(int j = right; right < s.length(); ++j){
    
    
                if(s[i] == s[j])
                    cur_str += s[j];
                else{
    
    
                    right = j;
                    break;
                }
            }
            while(left >= 0 && right < s.length()){
    
    
                if(s[left] == s[right])
                    cur_str = s[left] + cur_str + s[right];
                else
                    break;
                left --;
                right ++;
            }
            max_str = (max_str.size() < cur_str.size() ? cur_str : max_str);
            if (s.length() - i < max_str.size() / 2)
                break;
        }
        return max_str;
    }
};

結果を送信する
ここに画像の説明を挿入します

解決策 2

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        if(s.size() <= 1)
            return s;
        // Construct dp [i] [j] to indicate whether the substring of the subscripts i to j of the string is a palindrome string
        vector<vector<int>> dp(s.size(), vector<int>(s.size()));
        int start = 0, end = 0;
        // A single character is a palindrome string
        for(int i = 0;i < s.size(); ++i) 
            dp[i][i] = true;
        // Traverse from a minimum length of 2
        for(int len = 2; len <= s.size(); ++len){
    
    
            for(int i = 0; i < s.size() - len + 1; ++i){
    
    
                // Unequal first and last characters
                if(s[i] != s[i + len - 1])
                    dp[i][i + len - 1] = false;
                else{
    
    
                    if (len <= 2)
                        dp[i][i + len - 1] = true;
                    // Determine whether the included string is a palindrome string
                    else 
                        dp[i][i + len - 1] = dp[i + 1][i + len - 2];
                }
                // Update the beginning and end positions of the maximum palindrome string
                 if (dp[i][i + len - 1] && len >= end - start + 1){
    
    
                    start = i;
                    end = i + len - 1;
                 }
            }
        }
        return s.substr(start, end - start + 1);
    }
};

結果を送信する
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/qq_44116998/article/details/130465264