LeetCode1147 段式回文
Posted __rookie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode1147 段式回文相关的知识,希望对你有一定的参考价值。
段式回文 其实与 一般回文 类似,只不过是最小的单位是 一段字符 而不是 单个字母。
举个例子,对于一般回文 "abcba" 是回文,而 "volvo" 不是,但如果我们把 "volvo" 分为 "vo"、"l"、"vo" 三段,则可以认为 “(vo)(l)(vo)” 是段式回文(分为 3 段)。
给你一个字符串 text,在确保它满足段式回文的前提下,请你返回 段 的 最大数量 k。
如果段的最大数量为 k,那么存在满足以下条件的 a_1, a_2, ..., a_k:
每个 a_i 都是一个非空字符串;
将这些字符串首位相连的结果 a_1 + a_2 + ... + a_k 和原始字符串 text 相同;
对于所有1 <= i <= k,都有 a_i = a_{k+1 - i}。
示例 1:
输入:text = "ghiabcdefhelloadamhelloabcdefghi"
输出:7
解释:我们可以把字符串拆分成 "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)"。
示例 2:
输入:text = "merchant"
输出:1
解释:我们可以把字符串拆分成 "(merchant)"。
示例 3:
输入:text = "antaprezatepzapreanta"
输出:11
解释:我们可以把字符串拆分成 "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)"。
示例 4:
输入:text = "aaa"
输出:3
解释:我们可以把字符串拆分成 "(a)(a)(a)"。
这个还是可以用动态规划来解决,用dp[i]记录到达i这个位置(对称,所以只用处理左半部分)的最多的段数。
外层循环1-n/2,内层从已知的最大段数的位置left一直到外层位置,看能不能增加段数。
1 class Solution { 2 public: 3 int longestDecomposition(string text) { 4 int len=text.size(); 5 int left=0; 6 int *dp=new int[len/2+1]; 7 char* ch=(char*)text.c_str(); 8 for(int i=0;i<len/2+1;++i) 9 dp[i]=-1; 10 dp[0]=0; 11 12 for(int i=1;i<=len/2;++i){ 13 for(int j=left;j<i;++j){ 14 if(dp[j]==-1) continue; 15 if(!check(ch,j,i,len)) continue; 16 dp[i]=dp[j]+1; 17 left=i; 18 } 19 } 20 return max(1,dp[left]*2+(left*2==len?0:1)); 21 } 22 23 bool check(char* ch,int j,int i, int n){ 24 for(int m=j;m<i;++m){ 25 if(ch[m]!=ch[n-i+(m-j)]) return false; 26 } 27 return true; 28 } 29 };
还可以直接用双指针+贪心解决。左指针移动到和有指针的位置的时候,比较pre-i和右指针开始往左相同长度的子串(pre为之前已经匹配到的最右位置)。如果能匹配就右指针往左移动,如果不能匹配就左指针继续右移。结束循环的条件为左指针超过了右指针(一次匹配后右指针左移,发生在长度为偶数的情况下);或者左指针等于右指针(发生在奇数位的情况或者没有匹配的情况下)。
1 class Solution: 2 def longestDecomposition(self, text: str) -> int: 3 n = len(text) 4 i, pre_i = 0, -1 5 ans = 0 6 j = n - 1 7 while i <= j: # 写成while True也行 8 while text[i] != text[j]: # 一定会结束 9 i += 1 10 # print("i, j:",i, j) 11 if i == j: 12 ans += 1 13 break 14 elif i < j: 15 l = i - pre_i 16 flag = True 17 for k in range(0, l): 18 if text[j - k] == text[i - k]: 19 continue 20 else: 21 flag = False 22 break 23 if flag: 24 # 程序成功遍历结束 25 pre_i = i 26 i += 1 27 j = j - l 28 ans += 2 29 else: 30 i += 1 31 else: 32 break 33 return ans 34 35 作者:horizonlc-codingMyHero 36 链接:https://leetcode-cn.com/problems/longest-chunked-palindrome-decomposition/solution/hen-jian-dan-de-jian-dan-bian-li-by-horizonlc-codi/ 37 来源:力扣(LeetCode) 38 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以上是关于LeetCode1147 段式回文的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode-5150 Longest Chunked Palindrome Decomposition(段式回文)