1. 程式人生 > >Manacher演算法(馬拉車演算法)講解

Manacher演算法(馬拉車演算法)講解

Manacher演算法:是一種高效的找出一個字串中迴文序列的最大值的演算法。時間複雜度為O(n);

我們正常的對於字串的迴文串的求法。是對從i向兩端延伸。時間複雜度過不去很多題。所以manacher演算法的優勢就要展現了。

我們可以思考一個問題我們是否能不用每次都從i點來向兩邊擴充套件。答案是可以的。我們可以利用前面算好的迴文串長度來優化當前迴文串長度的查詢。

在詳細講這個演算法之前。來明晰一些要用上資料結構,以及其含義。

p【i】:代表以i為中點的迴文串長度。

mx:當前迴文串的最右端點的位置。

id:當前最靠右端迴文串的中點位置。

好了,上面的概念不理解沒有關係,但是要記住,他們各自都代表什麼。

Manacher演算法的第一步:對原字串的預處理。就是在字元中間新增#號。具體這一步的用法是用來解決單雙數字符串的問題。舉個例子就能明白了。

例如:對於字串 aba來說,經過處理後將會變成@#a#b#a#。字串個數為奇數。

    對於字串 abab來說,經過處理後將會變成@#a#b#a#b#。字串個數為奇數。

細心地同學會發現。為什麼前面有個@呢。讓s【0】 = ‘@’。的話會方便字串下標的處理。

Mancher演算法的第二步:遍歷陣列。對於任意i位置。我們要取得i關於id對稱的位置j。因為id是半徑長度為mx-id的迴文串。所以i位置的迴文情況是和關於id對稱點j的迴文情況是相等的。舉個例子

@   #   b   #   a   #   b   #   a   #   e   #   a   #   b   #   a   #   b   #;

0    1   2   3    4   5   6   7   8   9  10  11 12 13 14 15 16 17 18  19

                                  j                   id                 i                      mx

                            id-(i-id) 

p【】                        3                                         3

當i = 14

p【i】 = p【id-(i-id)】= 3;

但是這只是其中的一種情況而已。

再舉一個例子:

@   #   e   #   a   #   b   #   a   #   e   #   a   #   b   #   a   #   d   #

0     1   2   3   4   5   6   7   8   9  10 11 12 13 14 15 16  17 18 19

                                 j                  id                  i                   mx        

                              id-(i-id)

p【】                      5                                           3

為什麼會出現這種情況的呢?

我們知道對於這個例子當i = 14時,當前最長的迴文串時以id為中心半徑長度為mx - id。所以關於e這個字元兩邊的aba這一段一定是相等。但是不能保證左邊的以b為中心的迴文串的長度只到兩邊的a。這個迴文串有可能更長。這樣就導致左邊的b中p【j】的值不等於p【i】。但是我們可以知道的是兩段aba是一定相等的。

所以綜合這兩種情況。我們可以得出

p【i】 = min(mx-id ,p【id-(i - id)】);

當然了這是在mx > i 的情況 

不在這個情況的下

p【i】 = 1;

manacher演算法到這裡就完成了?naive 還有一步。就是再向兩邊來找,也就是去延伸i點的迴文串。然後比較 更新 id 和mx的值。

下面看一下具體實現過程:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 20000005;
char str[N];
int p[N];
void 
manacher(char *s,int len){
	p[0] = 1;
	int mx = 0 , id  = 0;
	for(int i = 1 ;i < len ; i ++){
		p[i] = mx > i ? min(p[id*2 - i],mx-i) : 1;
		while(s[i+p[i]] == s[i-p[i]])
			p[i] ++;
		if(i+p[i] > id + p[id]){
			id = i;
			mx = i +p[i];
		} 
	}
}
int main(){
	while(scanf("%s",str)){
		int len = strlen(str);
		for(int i = len ; i >= 0; i --){
			str[(i << 1) + 1] = '#';
			str[(i << 1) + 2] = str[i];
		}
		str[0] = '@';
		len = len*2 +2;
		manacher(str,len);
		int ans = 0;
		for(int i = 0 ; i < len ; i++)
			ans = max(ans,p[i]-1);
		printf("%d\n",ans);
	}
	return 0;
}


相關推薦

Manacher演算法馬拉車演算法講解

Manacher演算法:是一種高效的找出一個字串中迴文序列的最大值的演算法。時間複雜度為O(n);我們正常的對於字串的迴文串的求法。是對從i向兩端延伸。時間複雜度過不去很多題。所以manacher演算法的優勢就要展現了。我們可以思考一個問題我們是否能不用每次都從i點來向兩邊擴

【HDU - 3068】最長迴文Manacher演算法馬拉車演算法求最長迴文子串

題幹: 給出一個只由小寫英文字元a,b,c...y,z組成的字串S,求S中最長迴文串的長度.  迴文就是正反讀都是一樣的字串,如aba, abba等 Input 輸入有多組case,不超過120組,每組輸入為一行小寫英文字元a,b,c...y,z組成的字串S  兩

第四章作業-串-計算機17級 7-1 最長對稱子串 25 分四種方法求解暴力列舉+動態規劃+中心擴充套件+manacher演算法馬拉車

7-1 最長對稱子串 (25 分) 對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定Is PAT&TAP symmetric?,最長對稱子串為s PAT&TAP s,於是你應該輸出11。 輸入格式: 輸入在一行中給出長度不超過1000的非空字串

資料結構與演算法隨筆之------最長迴文子串四種方法求解暴力列舉+動態規劃+中心擴充套件+manacher演算法馬拉車

所謂迴文串,就是正著讀和倒著讀結果都一樣的迴文字串。 比如: a, aba, abccba都是迴文串, ab, abb, abca都不是迴文串。 一、暴力法 方法一:直接暴力列舉 求每一個子串時間複雜度O(N^2), 判斷子串是不是迴文O(N),兩者是相乘關係,所以時間

牛客網刷題 尋找回文串馬拉車演算法

  題目:設計一個演算法,尋找字串中的最長迴文子串。 輸入一行:一個字串 輸出兩行:最長迴文子串的長度(無則輸出0) 最長迴文子串(無則輸出空行) 思路: 一個迴文串它的對稱中心可能是某個字元(aba),也可能是某兩個字元之間(aa),理論上我們應該分類討論?但實際

L2-008. 最長對稱子串馬拉車演算法

對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定”Is PAT&TAP symmetric?”,最長對稱子串為”s PAT&TAP s”,於是你應該輸出11。 輸入格式: 輸入在一行中給出長度不超過1000的非空字串。 輸出格式:

為什麼我要放棄javaScript資料結構與演算法第一章—— JavaScript簡介

資料結構與演算法一直是我算比較薄弱的地方,希望通過閱讀《javaScript資料結構與演算法》可以有所改變,我相信接下來的記錄不單單對於我自己有幫助,也可以幫助到一些這方面的小白,接下來讓我們一起學習。 第一章 JavaScript簡介 眾所周知,JavaScript是一門非常強大的程式語言,不僅可以用於

小白python學習——機器學習篇——k-近鄰演算法KNN演算法

一、演算法理解 一般給你一資料集,作為該題目的資料(一個矩陣,每一行是所有特徵),而且每一組資料都是分了類,然後給你一個數據,讓這個你預測這組資料屬於什麼類別。你需要對資料集進行處理,如:歸一化數值。處理後可以用matplotlib繪製出影象,一般選兩個特徵繪製x,y軸,然後核心是計算出預測點到

機器學習實戰Apriori演算法關聯分析

目錄 0. 前言 1. Apriori 演算法尋找頻繁項集 2. 從頻繁項集中挖掘關聯規則 3. 實戰案例 3.1. apriori演算法發現頻繁項集和關聯規則 學習完機器學習實戰的Apriori,簡單的做個筆記。文中部分描述屬於

基於分解的多目標進化演算法MOEA/D

目錄 1、MOEA/D的特點 2、 MOEA/D的分解策略 3、MOEA/D的流程 基於分解的多目標進化演算法(Multi-objectiveEvolutionary Algorithm Based on Decomposition, MOEA/D)將多目標優化問題被轉

經典排序演算法Java版

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

關於離散小波框架變換以及多孔演算法a trous的學習感悟

最近學習小波變換與非抽取的小波變換,尤其是非抽取的小波變換,在學習感覺非常困惑,最後也得出一點感悟,不知是否正確,僅供參考,相互學習! 首先,我是在文獻[1]瞭解到離散小波框架的,在文獻[2]瞭解到多孔演算法的。學習過程中,查看了很多圖書以及網上的資料,講得都很抽象,部落格[3]對我的幫助很大。

LL(0)語法分析演算法完整版 ----編譯原理試驗

                                          &

常用演算法Java表述

 氣泡排序(Bubble Sort) 氣泡排序:一種交換排序,它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。穩定排序演算法 時間複雜度 O(n2),裡層迴圈每趟比較第 j 項和第 j+1項,如果前項大於後項,則發生交換。缺點是每次比較後都可能發生交換,

深度學習中的優化演算法待更

    優化演算法可以使得神經網路執行的速度大大加快,機器學習的應用是一個高度依賴經驗的過程,伴隨著大量迭代的過程,需要訓練諸多的模型來找到最合適的那一個。其中的一個難點在於,深度學習沒有在大資料領域發揮最大的效果,我們可以利用一個巨大的資料集來訓練神經網路,

反向傳播演算法BP演算法

BP演算法(即反向傳播演算法),適合於多層神經元網路的一種學習演算法,它建立在梯度下降法的基礎上。BP網路的輸入輸出關係實質上是一種對映關係:一個n輸入m輸出的BP神經網路所完成的功能是從n維歐氏空間向m維歐氏空間中一有限域的連續對映,這一對映具有高度非線性。它的資訊處理能力來源於簡單非線性函式的多

累加和校驗演算法CheckSum演算法

因為外界總會對電路存在或多或少的干擾,對於數字訊號,很可能導致傳輸的資料出現千差萬別。對於很多需要傳輸資料的場合,尤其是一些資料可能會影響一些硬體的動作(諸如嵌入式的一些裝置、機器人等),錯誤的資料可能會帶來一些隱性風險,想想都可怕。 由於本人是嵌入式相關領域的,平時玩的都是微控制器,當然微

對稱矩陣與壓縮儲存演算法java實現

一、問題描述 實現一個對稱矩陣的壓縮儲存 二、演算法分析 對稱矩陣的特點:a[i][j] = a[j][i].即所有元素關於對角線對稱 所以可以將對稱矩陣的下三角儲存在一個數組物件SA中,儲存方式是, SA[0] = a[0][0] SA[1] = a[1][0]  

機器學習中的優化演算法附程式碼

摘要 > 優化演算法指通過改善訓練方式,來最小化(或最大化)損失函式E(x) 區域性最優問題 區域性最優與鞍點。在神經網路中,最小化非凸誤差函式的另一個關鍵挑戰是避免陷於多個其他區域性最小值中。實際上,問題並非源於區域性極小值,而是來自鞍點,即一個維度向上傾斜且

整合演算法ensemble learning--競賽和論文神器

就拿決策樹來說,比如如果一顆決策樹效果不行,就用多顆決策樹,這樣就構成隨機森林。 目的:讓機器學習效果更好,單個不行,就用多個一起。 整合演算法一、 bagging演算法:並行訓練多個M模型(如決策樹)取平均或者其他方式彙總,如果就拿決策樹來說,訓練M顆決策樹取預測資料,就會有M個結果,