[LeetCode] 1147. Longest Chunked Palindrome Decomposition 段式回文



You are given a string text. You should split it to k substrings (subtext1, subtext2, ..., subtextk) such that:

  • subtexti is a non-empty string.
  • The concatenation of all the substrings is equal to text (i.e., subtext1 + subtext2 + ... + subtextk == text).
  • subtexti == subtextk - i + 1 for all valid values of i (i.e., 1 <= i <= k).

Return the largest possible value of k.

Example 1:

Input: text = "ghiabcdefhelloadamhelloabcdefghi"
Output: 7
Explanation: We can split the string on "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)".

Example 2:

Input: text = "merchant"
Output: 1
Explanation: We can split the string on "(merchant)".

Example 3:

Input: text = "antaprezatepzapreanta"
Output: 11
Explanation: We can split the string on "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)".

Example 4:

Input: text = "aaa"
Output: 3
Explanation: We can split the string on "(a)(a)(a)".

Constraints:

  • 1 <= text.length <= 1000
  • text consists only of lowercase English characters.

這道題是關於段式回文的,想必大家對回文串都不陌生,就是前后字符對應相同的字符串,比如 noon 和 bob。這里的段式回文相等的不一定是單一的字符,而是可以是字串,參見題目中的例子,現在給了一個字符串,問可以得到的段式回文串的最大長度是多少。由於段式回文的特點,你可以把整個字符串都當作一個子串,則可以得到一個長度為1的段式回文,所以答案至少是1,不會為0。而最好情況就是按字符分別相等,那就變成了一般的回文串,則長度就是原字符串的長度。比較的方法還是按照經典的驗證回文串的方式,用雙指針來做,一前一后。不同的是遇到不相等的字符不是立馬退出,而是累加兩個子串 left 和 right,每累加一個字符,都比較一下 left 和 right 是否相等,這樣可以保證盡可能多的分出來相等的子串,一旦分出了相等的子串,則 left 和 right 重置為空串,再次從小到大比較,參見代碼如下:


解法一:

class Solution {
public:
    int longestDecomposition(string text) {
        int res = 0, n = text.size();
        string left, right;
        for (int i = 0; i < n; ++i) {
            left += text[i], right = text[n - i - 1] + right;
            if (left == right) {
                ++res;
                left = right = "";
            }
        }
        return res;
    }
};

我們也可以使用遞歸來做,寫法更加簡潔一些,i從1遍歷到 n/2,代表的是子串的長度,一旦超過一半了,說明無法分為兩個了,最終做個判斷即可。為了不每次都提取出子串直接進行比較,這里可以先做個快速的檢測,即判斷兩個子串的首尾字符是否對應相等,只有相等了才會提取整個子串進行比較,這樣可以省掉一些不必要的計算,參見代碼如下:


解法二:

class Solution {
public:
    int longestDecomposition(string text) {
        int n = text.size();
        for (int i = 1; i <= n / 2; ++i) {
            if (text[0] == text[n - i] && text[i - 1] == text[n - 1]) {
                if (text.substr(0, i) == text.substr(n - i)) {
                    return 2 + longestDecomposition(text.substr(i, n - 2 * i));
                }
            }
        }
        return n == 0 ? 0 : 1;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1147


類似題目:


參考資料:

https://leetcode.com/problems/longest-chunked-palindrome-decomposition/

https://leetcode.com/problems/longest-chunked-palindrome-decomposition/discuss/350560/JavaC%2B%2BPython-Easy-Greedy-with-Prove

https://leetcode.com/problems/longest-chunked-palindrome-decomposition/discuss/350762/Java-0ms-concise-beats-100-(both-time-and-memory)-with-algo


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM