字符窜同构的性质:同构字符窜拥有最小和最大的表示方法;

最长回文子窜:

1.首先暴力法:(n三方)

枚举每个起点和终点,然后单向扫描判断是不是回文子窜;

2.中心扩散法,(N方)

枚举每个中点,向外扩散,看以他为中心的回文子窜的长度是多少;

易证:复杂度N方

3.O(N)的做法;

https://blog.csdn.net/afei__/article/details/83214042?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

我的理解:和扩展KMP有点相似,扩展KMP,我们为了不重复所以设定了破,po和ex[po],然后我们讨论i可能的答案是否已经包含在扫描的里面了,如果包含了直接赋值,没包含继续扫描;

我们对中心扩散的方法进行改进,

1.思想:    1)将原字符串S的每个字符间都插入一个永远不会在S中出现的字符(本例中用“#”表示),在S的首尾也插入该字符,使得到的新字符串S_new长度为2*S.length()+1,保证Len的长度为奇数(下例中空格不表示字符,仅美观作用);

例:S:       a  a  b  a  b  b  a

S_new:        #  a  #  a  #  b  #  a  #  b  #  b  #  a  #

2)根据S_new求出以每个字符为中心的最长回文子串的最右端字符距离该字符的距离,存入Len数组中,即S_new[i]—S_new[r]为S_new[i]的最长回文子串的右段(S_new[2i-r]—S_new[r]为以S_new[i]为中心的最长回文子串),Len[i] = r - i + 1;

S_new:        #  a  #  a  #  b  #  a  #  b  #  b  #  a  #

Len:            1  2  3  2  1   4  1  4  1  2  5   2  1  2  1

Len数组性质:Len[i] - 1即为以Len[i]为中心的最长回文子串在S中的长度。在S_new中,以S_new[i]为中心的最长回文子串长度为2Len[i] - 1,由于在S_new中是在每个字符两侧都有新字符“#”,观察可知“#”的数量一定是比原字符多1的,即有Len[i]个,因此真实的回文子串长度为Len[i] - 1,最长回文子串长度为Math.max(Len) - 1。

3)Len数组求解(线性复杂度(O(n))):

a.遍历S_new数组,i为当前遍历到的位置,即求解以S_new[i]为中心的最长回文子串的Len[i];

b.设置两个参数:sub_midd = Len.indexOf(Math.max(Len)表示在i之前所得到的Len数组中的最大值所在位置、sub_side = sub_midd + Len[sub_midd] - 1表示以sub_midd为中心的最长回文子串的最右端在S_new中的位置。起始sub_midd和sub_side设为0,从S_new中的第一个字母开始计算,每次计算后都需要更新sub_midd和sub_side;

c.当i < sub_side时,取i关于sub_midd的对称点j(j = 2sub_midd - i,由于i <= sub_side,因此2sub_midd - sub_side <= j <= sub_midd);当Len[j] < sub_side - i时,即以S_new[j]为中心的最长回文子串是在以S_new[sub_midd]为中心的最长回文子串的内部,再由于i、j关于sub_midd对称,可知Len[i] = Len[j];    当Len[j] >= sub.side - i时说明以S_new[i]为中心的回文串可能延伸到sub_side之外,而大于sub_side的部分还没有进行匹配,所以要从sub_side+1位置开始进行匹配,直到匹配失败以后,从而更新sub_side和对应的sub_midd以及Len[i];

d.当i > sub_side时,则说明以S_new[i]为中心的最长回文子串还没开始匹配寻找,因此需要一个一个进行匹配寻找,结束后更新sub_side和对应的sub_midd以及Len[i]。

我的理解:

实际上我们每次扫描得到了sub_mid和sub_side,利用回文串的对称性,我们来判断是否已经在答案里面了,不在的我们就继续扫描比较下去;

就是对中心扩散法的一种dp;

与那个啥z函数有点类似的想法,利用性质推到到已经求过的内容然后及进行求解,避免重复扫描;

void getlen(char *str)
{
 int ans=1,arm=0;
 memset(len,0,sizeof(len));
 int mid=0,side=1,i,j,r;
 len[0]=1;
 for(i=1;i<R;i++)
 {
  j=2*mid-i;
  if(j<0||j-len[j]<=mid-len[mid])
  {
   r=side-i;
   if(r==0) side++,r=1;
   while(i-r>=0&&str[i-r]==str[side])
   {
    r++;
    side++;
   }
   mid=i;
   len[i]=r;
  }
  else
   len[i]=len[j];
  if(ans<len[i])
  {
   ans=len[i];
   arm=i;
  }
 }
 if(ans-1<2)
 cout<<"No solution!\n";
 else
 {
  int r=arm+len[arm]-1,l=arm-(len[arm]-1);
  r--;
  l=l/2;r=r/2;
  cout<<l<<" "<<r<<"\n";
  for(int i=l;i<=r;i++)
   slove(s1[i]);
  cout<<"\n";
 }
}

最长回文子窜O(N)的更多相关文章

  1. LeetCode-5:Longest Palindromic Substring(最长回文子字符串)

    描述:给一个字符串s,查找它的最长的回文子串.s的长度不超过1000. Input: "babad" Output: "bab" Note: "aba ...

  2. 1. Longest Palindromic Substring ( 最长回文子串 )

    要求: Given a string S, find the longest palindromic substring in S. (从字符串 S 中最长回文子字符串.) 何为回文字符串? A pa ...

  3. 最长回文子序列(LPS)

    问题描述: 回文是正序与逆序相同的非空字符串,例如"civic"."racecar"都是回文串.任意单个字符的回文是其本身. 求最长回文子序列要求在给定的字符串 ...

  4. 最长回文子串(动规,中心扩散法,Manacher算法)

    题目 leetcode:5. Longest Palindromic Substring 解法 动态规划 时间复杂度\(O(n^2)\),空间复杂度\(O(n^2)\) 基本解法直接看代码 class ...

  5. [LeetCode] Longest Palindromic Substring 最长回文串

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  6. 求最长回文子串:Manacher算法

    主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...

  7. Manacher's algorithm: 最长回文子串算法

    Manacher 算法是时间.空间复杂度都为 O(n) 的解决 Longest palindromic substring(最长回文子串)的算法.回文串是中心对称的串,比如 'abcba'.'abcc ...

  8. leetcode-5 最长回文子串(动态规划)

    题目要求: * 给定字符串,求解最长回文子串 * 字符串最长为1000 * 存在独一无二的最长回文字符串 求解思路: * 回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文 ...

  9. 最长回文子串(Longest Palindromic Substring)-DP问题

    问题描述: 给定一个字符串S,找出它的最大的回文子串,你可以假设字符串的最大长度是1000,而且存在唯一的最长回文子串 . 思路分析: 动态规划的思路:dp[i][j] 表示的是 从i 到 j 的字串 ...

随机推荐

  1. Mol Cell Proteomics. | A Targeted Mass Spectrometry Strategy for Developing Proteomic Biomarkers: A Case Study of Epithelial Ovarian Cancer(利用靶向质谱策略进行上皮性卵巢癌病例的蛋白质组生物标志物研究) (解读人:王聚)

    文献名:利用靶向质谱策略进行上皮性卵巢癌病例的蛋白质组生物标志物研究 期刊名:Molecular & Cellular Proteomics 发表时间:(2019年7月) IF:5.41 单位 ...

  2. VsCode编辑器那些事

    1.怎么改成中文的? 按快捷键“Ctrl+Shift+P” 在框下点击“configur Display language" 会跳转至商店,选择插件下载“Chinese (Simplifie ...

  3. 使用 Vue.js 改写 React 的官方教程井字棋

    React 的官方教程井字棋很好的引导初学者一步步走进 React 的世界,我想类似的教程对 Vue.js 的初学者应该也会有启发,于是使用 Vue.js 进行了改写 可以先查看最终的结果,尝试点击体 ...

  4. ASP.NET Core 核心特性--宿主、启动、中间件

    宿主 public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().R ...

  5. 【洛谷】P2444 [POI2000]病毒——AC自动机

    题目链接 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段, ...

  6. [gcd]Codeforces Common Divisors

    Common Divisors time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  7. 五大经典卷积神经网络介绍:LeNet / AlexNet / GoogLeNet / VGGNet/ ResNet

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! LeNet / AlexNet / GoogLeNet / VGG ...

  8. Android ConstraintLayout 构建自适应界面

    原文链接 使用 ConstraintLayout 构建自适应界面 ConstraintLayout 可让您使用扁平视图层次结构(无嵌套视图组)创建复杂的大型布局.它与 RelativeLayout 相 ...

  9. PTA数据结构与算法题目集(中文) 7-25

    PTA数据结构与算法题目集(中文)  7-25 7-25 朋友圈 (25 分)   某学校有N个学生,形成M个俱乐部.每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈.一个学生可以同时属于若干 ...

  10. PTA | 1010 一元多项式求导 (25分)

    设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: ...