leetcode 1147
问题 Return the largest possible k
such that there exists a_1, a_2, ..., a_k
such that:
Each a_i
is a non-empty string;
Their concatenation a_1 + a_2 + ... + a_k
is equal to text
;
For all 1 <= i <= k
, a_i = a_{k+1 - i}
.
Example 1:
1 2 3 Input: text = "ghiabcdefhelloadamhelloabcdefghi" Output: 7 Explanation: We can split the string on "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)".
Example 2:
1 2 3 Input: text = "merchant" Output: 1 Explanation: We can split the string on "(merchant)".
Example 3:
1 2 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:
1 2 3 Input: text = "aaa" Output: 3 Explanation: We can split the string on "(a)(a)(a)".
Constraints:
text
consists only of lowercase English characters.
1 <= text.length <= 1000
分析 思路1: 使用动态规划
思路2: 贪心算法,每次总是尽量取最小的能够匹配的最长公共前后缀。证明:https://leetcode.com/problems/longest-chunked-palindrome-decomposition/discuss/350560/JavaC%2B%2BPython-Easy-Greedy-with-Prove
代码1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : int longestDecomposition (string text) { int n = text.size(); vector <int > dp(n, -1 ); dp[n/2 ] = n%2 ? 1 : 0 ; return dfs(text, dp, 0 ); } int dfs (const string &text, vector <int > &dp, int i) { if (dp[i] >= 0 ) return dp[i]; int ret = 1 ; for (int k = 1 ; i+k <= text.size()/2 ; ++k) { if (text.substr(i, k) == text.substr(text.size()-i-k, k)) { ret = max(ret, 2 +dfs(text, dp, i+k)); } } return dp[i] = ret; } };
代码2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : int longestDecomposition (string text) { string l, r; int n = text.size(); int ans = 0 ; for (int i = 0 ; i < n/2 ; ++i) { l += text[i]; r = text[n-i-1 ] + r; if (l == r) { ans += 2 ; l = r = "" ; } } if ((n%2 == 0 ) && l == "" && r == "" ) return ans; return ans+1 ; } };