回文串

求字符串中回文子串的个数(回文树详解)

£可爱£侵袭症+ 提交于 2020-02-02 20:28:00
写法一: #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<vector> #include<cmath> #include<string> #include<map> #include<queue> using namespace std; const int MAXN = 1005; struct node { int next[26];//指向在当前节点串的基础上左右两边同时添加相同字符后形成的回文串 int len;//此节点串的长度 int sufflink;//此节点的最长后缀回文串的指针 int num;//此节点中的回文子串的个数 }; int len; char s[MAXN]; node tree[MAXN]; int num; // node 1 - root with len -1, node 2 - root with len 0 int suff; // max suffix palindrome long long ans; bool addLetter(int pos) { int cur = suff;//当前以pos-1结尾的最长后缀回文子串的节点标号(即p的长度) int curlen; int let = s[pos] -

【leetcode】5.最长回文子串【cpp】

こ雲淡風輕ζ 提交于 2020-01-29 00:59:44
题目:[leetcode]5. 最长回文子串 方法一:暴力求解,但是只能过47个测试用例,再往后会超时。 # include <algorithm> # include <string> # include <iostream> using namespace std ; class Solution { public : bool IsPalindromeStr ( string s ) { string tmp = s ; reverse ( s . begin ( ) , s . end ( ) ) ; if ( tmp == s ) { // 判断是否回文字符串,只需要反转一下字符串进行比较即可。是回文,会相等。 return true ; } else { return false ; } } string longestPalindrome ( string s ) { int len = s . length ( ) ; string res ; int i , j ; int max = 0 ; for ( i = 0 ; i < len ; i ++ ) { for ( j = 1 ; j <= len - i ; j ++ ) { if ( IsPalindromeStr ( s . substr ( i , j ) ) ) { if ( j > max ) {

Leetcode初学——最长回文子串

荒凉一梦 提交于 2020-01-18 00:36:29
题目 对于这道题目,我决定采用暴力破解的方法,列举所有子串来判断是否是回文,不过我打算从最长的到最小的,这样可以减少列举次数 class Solution { public String longestPalindrome(String s) { int length=s.length(); int i=0,j=length; int maxLength=length; String temp=""; while(i<j){ temp=s.substring(i,j); if(isPalindrome(temp)) break; if(j==length){ i=0; j=--maxLength; }else{ i++; j++; } } return temp; } private boolean isPalindrome(String s) { int i=0; int j=s.length()-1; while (i<j){ if (s.charAt(i++)!=s.charAt(j--))return false; } return true; } } 这里我直接使用了上一篇文章用到的判断回文数的方法 感兴趣的可以看我的上一篇文章 Leetcode初学——回文数 https://blog.csdn.net/qq_39377543/article/details

最长回文子串--力扣

吃可爱长大的小学妹 提交于 2020-01-10 04:10:33
5种解法: 1.最长公共子串 2.暴力法 3.动态规划 4.中心扩展法 5.Manacher法 以下记录大佬题解: 算法: 什么叫回文串? 如果一个字符串正着读和反着读是一样的,那它就是回文串。 中心扩展算法 我们观察到回文中心的两侧互为镜像。因此,回文可以从它的中心展开,并且只有 2n - 1 个这样的中心。 你可能会问,为什么会是 2n - 1 个,而不是 n 个中心? 因为回文的中心要区分单双。 假如回文的中心为 双数,例如 abba,那么可以划分为 ab bb ba,对于n长度的字符串,这样的划分有 n-1 种。 假为回文的中心为 单数,例如 abcd, 那么可以划分为 a b c d, 对于n长度的字符串,这样的划分有 n 种。 对于 n 长度的字符串,我们其实不知道它的回文串中心倒底是单数还是双数,所以我们要对这两种情况都做遍历,也就是 n+(n-1) = 2n - 1,所以时间复杂度为 O(n)。 当中心确定后,我们要围绕这个中心来扩展回文,那么最长的回文可能是整个字符串,所以时间复杂度为 O(n)。 所以总时间复杂度为 O(n^2) 代码如下: string longestPalindrome(string s) { if (s.length() < 1) { return ""; } int start = 0, end = 0; for (int i = 0;

LeetCode中等:最长回文子串

你。 提交于 2020-01-04 03:08:22
最长回文子串(C#) 题目描述:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 1. 暴力法 思路:对所有子串遍历,判断是否为回文串。 显然需要一个函数判断一个字符串是否为回文串 public bool isPalindromic ( string s ) { for ( int i = 0 ; i < s . Length / 2 ; i ++ ) { if ( s [ i ] != s [ s . Length - i - 1 ] ) return false ; } return true ; } ok,接下来进行遍历 public string LongestPalindrome ( string s ) { string result = "" ; int MaxLength = 0 ; string current_s = "" ; for ( int i = 0 ; i < s . Length ; i ++ ) { for ( int j = i ; j < s . Length ; j ++ ) { current_s = s . Substring ( i , j - i + 1 ) ; result = isPalindromic ( current_s ) && current_s . Length > result

最长回文子串

故事扮演 提交于 2019-12-23 00:33:36
题目描述 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 (1)输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 (2)输入: “cbbd” 输出: “bb” 解题思路 分析:要判断一个字符串是否是回文串,需要以下两步才能判断其是否为回文串:(1)其子串为回文串(2)在子串的基础上左右分别加一个相等的字符; dp [ left , right ] = ( s [ left ] == s [ right ] && ( right - left < 2 || dp [ left + 1 , right - 1 ] ) ) ; 那么在这个过程中,就必须记录其子串是否为回文串,所以,实现的代码中给出了一个bool类型的二维数组,用来保存其子串是否为回文的判定结果。 bool [ , ] dp = new bool [ s . Length , s . Length ] ; 另外,在此过程中要实时更新最长的回文串,只有当目前的回文串的长度比保存的最长的回文串长时才需要将其更新。 result = dp [ left , right ] && result . Length < s . Substring ( left , right - left + 1 ) . Length ? s . Substring (

最长的回文子串(四种方法)

早过忘川 提交于 2019-12-09 21:39:28
本文是观看了很多博客,最后整理而成…… 回文串: “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。 手动判断 该字符串是否为回文串: #include <iostream> using namespace std; int main(){ string str; int i, j; while (cin >> str){ int flag = 1; for (i = 0,j = str.length()-1; i <= j; i++,j--){ if (str[i] != str[j]){ flag = 0; break; } } if (flag) cout << "YES" << endl; else cout << "NO" << endl; } return 0; } 利用函数判断 给字符串是否为回文串: #include<iostream> #include<algorithm> using namespace std; int hui(string s){ string s1 = s; reverse(s.begin(), s.end()); return s==s1; } int main(){ string s; cin >> s; if(hui(s)) cout << "yes"; else cout << "no";

LeetCode 5 最长回文子串 Manacher线性算法

纵然是瞬间 提交于 2019-12-09 11:41:08
题目链接:https://oj.leetcode.com/problems/longest-palindromic-substring/ 回文串即正向反向序列都一样的连续序列 如abba,abcba... 为了统一回文串的偶数情况和奇数情况,可以向串中插入不相关的字符,例如abba->#a#b#b#a#, abcba->#a#b#c#b#a# 建立数组arr[]记录主串中以第i个字符为中心的回文串向右延伸的长度(即向右覆盖长度,不包括s[i]) 例如: 第一种情况: 设变量mx为当前向右最大覆盖位置下标,id为该回文串对称中心下标。在例子中,达到最右覆盖位置的为index=5,覆盖到5+arr[5]=8.所以,此时,mx=8,id=5 在计算arr[7]时(图中‘?’处i=7),可以利用arr[0~6]的值,发现7位于以id为对称中心的覆盖范围内(图中黄色部分)。并且,i=7的对称位置id*2-i=3的覆盖范围(蓝色部分)并未超出id的覆盖范围(黄色部分),所以,arr[7]可直接利用arr[3]的值,令arr[7]=arr[3]. 另外一种情况:i未超出黄色部分,但蓝色不服超出了黄色部分。如下图: 此时,arr[7]的值至少为其关于id=5的对称位置:arr[3].所以,先为arr[7]赋初值=arr[3].然后,再从(i+arr[i]+1),(i-arr[i]-1

最长回文子串(Manacher算法)

自闭症网瘾萝莉.ら 提交于 2019-12-04 20:18:31
Manacher算法求最长回文子串 给定一个字符串,求它的最长回文子串,例如 "1232231" 的最长回文子串为 "3223" 。用 Manacher算法 可以在O(N)时间内得到结果。 — 目录 — Manacher算法求最长回文子串 1 题目描述 2 分析解法 普通解法 改进 3算法思路 Manacher算法思路 4 具体过程 Manacher算法过程 5 实例代码 1> 题目描述 给定一个长度小于100的字符串,求它的最长回文子串的长度 样例输入: 12212321 样例输出 6 2> 分析解法 普通解法 通常情况下我们会想到的方法是:遍历字符串的各个字符,然后对每一个字符找到以它为中心的最长回文串,遍历结束后再将得到的最大串长输出即可。 不难得出,上述方法的时间复杂度为 O ( N 2 ) //--> ,而且对于 "中心位置" 这个概念还要分两种情况: 例如对字符串 S ,此时遍历到的某个字符 a : a对应的回文子串长度为奇数,形如 BaB ; a对应的回文子串长度为偶数,形如 BaaB ; 因此该算法是不太合理的,但是对于 "中心位置" 需要分奇偶情况的问题,我们可以有很好的办法来解决。 改进 为了解决奇偶问题,首先在每个字符的两边插入一个特殊符号 '#' ,同时为了方便在代码中处理数组越界问题,在插入后的字符串最左边增加起始符号 '$' 。 例如,字符串

高效的求最长回文子串的算法——Manacher

£可爱£侵袭症+ 提交于 2019-12-04 20:18:15
GDOI市选出了一道关于Manacher的题目,于是打算学一下,但因为网络流鸽了一阵,最近才学完,学完后表示复杂度有点迷。 Manacher算法简介 Manacher,俗称马拉车,是由一位名叫Manacher的人与1975年提出的,这个算法让求最长回文子串的复杂度从O(n^2)下降到了O(n)。 Manacher的思想 先从n方算法说起,n方算法是每一位都向两边扩展,直到不回文。这个算法只是对当前位置进行操作,而Manacher算法将前面算出的值进行记录,用于后续的处理,从而降低复杂度。 我们平时用n^2算法处理的时候就会考虑到一个问题,就是一个回文串的长度,如果是像aaa一样的长度为奇数的串,它的中心是一个字符;如果是像abba一样长度为偶数的串,它的中心在两个字符中间,这样比较难处理。所以Manacher算法会在一个字符串每两个字符中间以及字符串头尾插入‘#’(也可以是其他的,有没有出现在原字符串中其实无所谓)。 如:abcdcba会变为#a#b#c#d#c#b#a#。 这里我们引入一个数组p[],p[i]表示以i为中心的最长回文串的半径长度。我们用表格举个例子: s # a # b # a # b # a # b # a # p 1 2 1 4 1 6 1 8 1 6 1 4 1 2 1 而更神奇的是以s[i]为中心的回文串长度就是p[i]-1。 Manacher的实现