zoukankan      html  css  js  c++  java
  • 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 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/rookiez/p/13341074.html
Copyright © 2011-2022 走看看