10

最长回文子串-马拉车

 3 years ago
source link: https://www.kirito41dd.cn/manacher/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

回文串是指是正着读和反着读都一样的字符串,比如abcba

最长回文子串是指在一个字符串中能找到的最长回文串,如这个字符串最长回文字串是最后6个字符:abacacbaaaab

用马拉车算法求一个串中的最长回文子串:

  1. 首先将字符串长度处理成奇数,如"abbc"处理成"$a#b#b#c#"
  2. 然后从左到右边遍历求出以每个字符为中心的回文半径Mp, 其中最大的那个回文半径就对应着最长的回文子串。

Manacher

算法实现如下:

https://blog-1256556944.cos.ap-nanjing.myqcloud.com/public/manacher.png

图中id表示如果以这个下标为中心,回文半径最远可以到达的位置是mx(这表示区间(id,mx][mx",id)是对称的, id位置就是对称轴)。

马拉车的思想是利用左边已经求出的回文半径,帮助计算右边的回文半径。如果我们要求下标i的回文半径,那么:

  • 2*id-i 指的就是是下标i关于id的对称位置i",(i肯定在id的右边,因为是从左往右遍历处理)

计算回文半径Mp[i]:

  1. 如果mx>i(图1,2),即id处的回文半径能够覆盖当前位置,那么i关于id的对称位置i"一定也在以id为中心的回文串中。

    i"位于id左边,所以i"的结果前面已经算出来了,直接得出i"的回文半径就是Mp[i"] = Mp[2*id-i]

    (图里左边的红色部分就是回文半径为Mp[i"]的回文串,右边是对称的部分)

    这时候计算i的回文半径还分两种情况:

    1. mx-i > Mp[2*id-i]
    2. mx-i < Mp[2*id-i]

    分别对应图1、2。Mp[i]的值选取两者中较小的那一个。

    因为图中只有同时被红色和绿色覆盖的,才关于i对称,其他的未知。

  2. 如果,mx <= i(图3),那么i的回文半径只能通过一次次比较求得。

细节见代码,返回值是最长回文串长度。

namespace Manacher{
	const int MAXN = 100;//字符串最大长度
	char Ma[MAXN*2];//处理后的字符串
	int Mp[MAXN*2];//每个位置的回文半径,max(Mp[i])-1就是最长回文长度
	int Manacher(const char s[], int len){
		int l = 0, ret = 0;
		Ma[l++] = '$';
		Ma[l++] = '#';
		for(int i = 0; i<len; i++){
			Ma[l++] = s[i];
			Ma[l++] = '#';
		}
		Ma[l] = 0;
		int mx = 0, id = 0; //从id处回文半径可以达到mx处
		for(int i = 0; i < l; i++){
			Mp[i] = mx > i ? min(Mp[2*id-i], mx - i) : 1;
			while(Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++;
			ret = max(Mp[i]-1,ret);
			if(i + Mp[i] > mx){
				mx = i + Mp[i];
				id = i;
			}
		}
		return ret;
	}
}

POJ3974 裸题


Recommend

  • 8

    395. 至少有 K 个重复字符的最长子串 其实,昨天我就打开了今天的打卡题,看到中等难度,我心里也是一咯噔,毕竟我现在的水平,简单也未必都能做出来的啊。 仔细读了题目意思后,发现,真的是难,超出了我能控制的范围了。晚上睡在床上就在...

  • 21

    算法笔记:最大数,加油站,无重复最长子串广发证券 技术工程师本文列举的都是LeetCode上middle难度的题最大数(Largest Number)

  • 8
    • sexywp.com 3 years ago
    • Cache

    3. 无重复字符的最长子串

    3. 无重复字符的最长子串 这道题的意思比较简单,我就不在这里抄题目了,可以去这里查看。简单说,就是在给定字符串里,找到一个连续的子串,这个子...

  • 9

    LeetCode 第 3 号问题:无重复字符的最长子串-程序员小吴 当前位置:程序员小吴 > LeetCodeAnimation > LeetCode 第 3 号问题:无重复字符的最...

  • 8
    • segmentfault.com 3 years ago
    • Cache

    最长回文子串 -- 三种解答

    给你一个字符串 s,找到 s 中最长的回文子串。示例 1: 输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。 示例 2: 输入:s = "cbbd" 输出:"bb" 示例 3: 输入:s = "a" 输出:"a" 示例 4: 输入:s = "ac" 输出:"a"...

  • 11
    • waiterxiaoyy.github.io 2 years ago
    • Cache

    LeetCode学习笔记——最长回文子串

    LeetCode学习笔记——最长回文子串

  • 13
    • leetcode.cn 2 years ago
    • Cache

    5. 最长回文子串

    5. 最长回文子串 - 力扣(LeetCode)5. 最长回文子串给你一个字符串 s,找到 s 中最长的回文子串。

  • 7
    • blog.51cto.com 2 years ago
    • Cache

    leetcode-无重复字符的最长子串

    leetcode-无重复字符的最长子串 精选 原创 小傻孩丶 2022-12-18 20:31:50...

  • 11
    • yuxinli1.github.io 2 years ago
    • Cache

    LeetCode 647: 回文子串

    给你一个字符串s,请你统计并返回这个字符串中回文子串的数目。 回文字符串是正着读和倒过来读一样的字符串。子字符串是字符串中由连续字符组成的一个序列。 具有不同开始位置或结束...

  • 8

    2023-07-31:用r、e、d三种字符,拼出一个回文子串数量等于x的字符串。 1 <= x <= 10^5。 来自百度。 精选 原创

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK