後綴數組,單字符串問題的天敵

如果想了解更多內容,歡迎關注我的微信公衆號:信息學競賽從入門到巔峯。

戳這裏獲得更好的閱讀體驗哦!

 

前兩期,我們重點介紹了後綴數組中sa、rank、height數組的求法。這些數組都具有優秀的性質,我來向大家介紹幾種後綴數組在解決單字符串問題上的經典應用。

 

最長重複子串(可重疊)

Problem:若字符串A在字符串B中出現兩次及以上,則稱A爲B的重複子串。給定字符串S,求S中出現位置可重疊的最長重複子串的長度。

Solution:回想height數組的定義,發現可重疊最長重複子串的長度就是height數組中的最大值。因爲height數組表示排名相鄰的後綴的最長公共前綴。顯然,公共前綴一定是出現了兩次以上的,所以最大的公共前綴的長度就是最長可重疊重複子串的長度。

 

 

最長重複子串(不可重疊)

Problem:問題描述與上題基本相同,但是要求重複子串的出現位置不可重疊。

Solution:考慮二分答案,把求值的問題變成判斷是非的問題。假設二分得到k,我們按照sa數組的順序把height大於等於k的後綴分成一組,如下圖。

分組過後,我們發現每一組的任意兩個後綴的最長公共前綴都是大於等於k的。這時,我們只要判斷是否存在一組後綴,該組後綴裏sa的最小值和最大值的差大於等於k就行了(sa存的是後綴的位置,兩個相差大於等於k意味着公共前綴至少有k個字符不重疊)。

 

最長重複子串(可重疊,需重複k次)

Problem:這個問題依然和上述問題類似,但是要求重複子串的出現次數要大於等於k次。

Solution:問題一的方法在這個問題上顯然是行不通的。我們仍然考慮二分答案並分組。這次每一組要判斷的是否存在一組後綴,在該組後綴中後綴個數是否大於等於k即可。

 

不同子串的個數

Problem:求一個字符串中有多少個不同的子串。

Solution:假設我們已經統計出了前k個後綴有幾個不同的子串,考慮新加一個後綴,這個後綴一共會產生n-sa[k+1]+1個新的子串(這裏要求新的子串必須是該後綴的前綴,這樣保證了每一個後綴產生的子串覆蓋了原字符串的所有子串)。這些新產生的子串中,有n-sa[k+1]+1-height[k+1]個子串是不同的(去掉與其他字符串的公共前綴)。那麼,不同子串的個數就很容易統計了。

 

重複次數最多的連續重複子串

Problem:求給定字符串的重複次數最多的連續重複子串。連續重複子串的定義是:若一個串S由T重複若干次得到,則稱T爲S的一個連續重複子串。

Solution:考慮枚舉連續重複子串的長度爲L。由抽屜原理我們知道,連續重複子串一定包含了S[0],S[L],S[2*L]……中的相鄰兩個。我們可以用後綴數組求解S[i*L],S[(i+1)*L]的往後能匹配多遠(即最長公共前綴),往前能匹配多遠(即把整個字符串反過來的“最長公共前綴”)。設總長度爲K,類似於KMP求循環節的思想,則該連續重複子串的重複次數爲K/L+1。

 

寫在最後

對於單字符串問題,後綴數組還能做到KMP,Manacher等算法所能做到的事,如求迴文串長度、最小循環節長度等,這裏就不在贅述了,讀者可以自行思考。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章