[网易]字符串回文分割

【题目】

将一个很长的字符串,分割成一段一段的子字符串,子字符串都是回文字符串。有回文字符串就输出最长的,没有回文就输出一个一个的字符。

例如:habbafgh

输出h,abba,f,g,h。

【思路一】

基于“最长回文子串算法”求出当前字符串的最长回文子串,就可以分成3部分

a、最长回文子串left部分

b、最长回文子串

c、最长回文子串right部分

然后分别求a和c的最长回文子串

递归至每部分都成单个字符+当前最长回文子串,就可以分解成最终结果。

【代码一】

#include<string>
#include<iostream>
using namespace std;

// beg end 用于返回最大回文串的范围
void MaxPalindromeNumber(string str,int& beg,int& end){
    int maxLen = 1,start = beg;
    int left,right;
    for(int i = beg;i <= end;i++){
        //奇数字串
        int oddLen = 1;
        left = i-1;
        right = i+1;
        while(left >= beg && right <= end && str[left] == str[right]){
            left--;
            right++;
            oddLen += 2;
        }
        //更新最大长度
        if(oddLen > maxLen){
            maxLen = oddLen;
            //记录当前最大回文串的起始位置
            start = left+1;
        }
        //偶数字串
        left = i;
        right = i+1;
        int evenLen = 0;
        while(left >= beg && right <= end && str[left] == str[right]){
            left--;
            right++;
            evenLen += 2;
        }
        //更新最大长度
        if(evenLen > maxLen){
            maxLen = evenLen;
            //记录当前最大回文串的起始位置
            start = left+1;
        }
    }
    beg = start;
    end = start + maxLen - 1;
}
int index = 0;
void SpilitPalindromeNumber(string str,int& beg,int& end){
    int lbeg = beg;
    int rend = end;
    //beg end 返回当前最大回文串的起始点和截止点
    MaxPalindromeNumber(str,beg,end);
    int lend = beg - 1;
    int rbeg = end + 1;
    // lbeg lend 最大回文串的左部
    // rbeg rend 最大回文串的右部
    if(lbeg <= lend){
        SpilitPalindromeNumber(str,lbeg,lend);
    }
    //控制格式输出
    if(index == 0){
        cout<<str.substr(beg,end-beg+1);
        index++;
    }
    else{
        cout<<","<<str.substr(beg,end-beg+1);
        index++;
    }
    if(rbeg <= rend){
        SpilitPalindromeNumber(str,rbeg,rend);
    }
}

int main(){
	string str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
	int beg = 0;
	int end = str.length()-1;
	SpilitPalindromeNumber(str,beg,end);
	return 0;
}

【思路二】

先将给定字符串翻转,然后和原来的字符串一起,这样就变成了最长公共子序列问题。

此时可以利用动态规划的思路来完成。

关于最长公共子序列问题可以参考<算法导论>里面有详细的说明

时间: 2024-10-10 09:40:34

[网易]字符串回文分割的相关文章

回文分割

周末女朋友不在家,打算做几题LeetCode的题目练练手,Pick One,随机抽中Palindrome Partitioning,题目如下: Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab", Ret

暑假集训7.11 字符串回文暴力

#include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned long long ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int i

【CF906E】Reverses(回文自动机,最小回文分割)

题意:给定两个长度相等的仅由小写字母组成的串A和B,问在A中最少选择多少段互不相交的子串进行翻转能使A和B相同 len<=5e5 思路:构造新串S=a[1]b[1]a[2]b[2]...a[n]b[n] 问题等价于求S的最小回文分割,其中需要每一段的长度都为偶数,注意长度为2的相当于没有翻转 把板子稍加修改即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsign

算法模板——线段树8 (字符串回文变换)

实现功能:输入一个长度为N的由26个大写字母组成的字符串,输入M条指令:"1 x y",将x到y的字串重组构成一个字典序最小的回文串,如果不能构成回文串输出False,否则True并完成变换:"2 x y"输出从x到y的子串:"3 x y t"将x到y的所有字全部变成chr(t+64)(即对应大写字母) 原理:用一个数组维护字母个数即可,然后再附带一个带tag的区间覆盖操作,实现回文串的重组 1 type 2 vec=array[0..26] o

字符串回文现象的递归判断

前面谈到了递归的一些思想,还有概念上的一些理解,这里试着用递归解决一些问题.比如回文. 回文是一种字符串,它正着读和反着读都是一样的.比如level,eye都是回文.用迭代的方法可以很快地判断一个字符串是否为回文.用递归的方法如何来实现呢? 首先我们要考虑使用递归的两个条件:澳门赌场玩法 第一:这个问题是否可以分解为形式相同但规模更小的问题? 第二:如果存在这样一种分解,那么这种分解是否存在一种简单情境? 先来看第一点,是否存在一种符合条件的分解.容易发现,如果一个字符串是回文,那么在它的内部一

说一下前天腾讯实习的笔试题--字符串回文问题(动态规划)

题目描述 最长回文子序列: 一个给定的字符串,求其最长回文子序列的长度; 一个回文子序列定义为原字符串的一个子序列去掉某些字符后生成的字符串为一个回文字符串; 例如cabbeaf:回文子序列有:c,a,aa,bb,,aba,abba,e,f,最长的就是abba,所以输出长度为4. 解题思路: 该问题为一个典型的动态规划问题,原串和反转串的最长公共子序列的长度即为该问题的解. 我实现的代码如下(我还多写了一些代码,用递归的方法来求解出了最长公共子序列的字符串): 1 #include <stdio

纪念逝去的岁月——C/C++字符串回文

判断字符串是否是回文: 1. 输入:hello world dlrow olleh 输出:1 2. 输入:nihao hello 输出:0 代码 #include <stdio.h> #include <string.h> int palindrome(char * p) { if(NULL == p) { return 0; } int iLen = strlen(p); int iHalf = iLen / 2; int i = 0, iEnd = iLen - 1; for(

Java实验--关于简单字符串回文的递归判断实验

首先题目要求写的是递归的实验,一开始没注意要求,写了非递归的方法.浪费了一些时间,所谓吃一堑长一智.我学习到了以后看实验的时候要认真看实验中的要求,防止再看错. 以下是对此次的实验进行的分析: 1)递归是运用到了栈的思想 2)回文是一段从中间开始倒置的文字,回代的过程中出现不同的符号的时候就说明这段文字不是回文了 根据上面对回文判断的分析,就拿最简单的121来说,要每个字符判断直至2所在的位置,然后依次回代判断前面的1和后面的1的位置(上述的描述就类似于栈的思想). 有关于栈还有递归其实我并不熟

19. Palindrome Partitioning &amp;&amp; Palindrome Partitioning II (回文分割)

Palindrome Partitioning Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab", Return [ ["aa","b"], ["a&q