字串最小表示法 O(n 演算法

2021-06-26 04:04:35 字數 1488 閱讀 3819

網上看了這篇文章後還是感覺有些地方講的沒有詳細的證明所以新增了一點 紅色字是博主寫的

求字串的迴圈最小表示:

上面說的兩個字串同構的,並沒有直接先求出min(s),而是通過指標移動,當某次匹配串長時,那個位置就是min(s)。而這裡的問題就是:不是給定兩個串,而是給出乙個串,求它的min(s),eg:min(「babba」) = 4。那麼由於這裡並非要求兩個串的同構,而是直接求它的最小表示,由於源串和目標串相同,所以處理起來既容易又需要有一些變化:我們仍然設定兩個指標,i, j,其中i指向0,j指向1,仍然採用上面的滑動方式:

(1)  利用兩個指標i, j。初始化時i指向0, j指向1。

(2)  k = 0開始,檢驗s[i+k] 與 s[j+k] 對應的字元是否相等,如果相等則k++,一直下去,直到找到第乙個不同,(若k試了乙個字串的長度也沒找到不同,則那個位置就是最小表示位置,演算法終止並返回)。則該過程中,s[i+k] 與 s[j+k]的大小關係,有三種情況:

證明的時候假設(i(a). s[i+k] > s[j+k],則i滑動到i+k+1處 --- 即s1[i->i+k]不會是該迴圈字串的「最小表示」的字首。

證明如下

(b). s[i+k] < s[j+k],則j滑動到j+k+1處,原因同上。

證明如下

(c). s[i+k] = s[j+k],則 k++; if (k == len) 返回結果。 

注:這裡滑動方式有個小細節,若滑動後i == j,將正在變化的那個指標再+1。直到p1、p2把整個字串都檢驗完畢,返回兩者中小於 len 的值。

(3)   如果 k == len, 則返回i與j中的最小值

如果 i >= len   則返回j

如果 j >= len   則返回i

實際上這題中 i,j 都可能存有ans 兩者互相更新,直到有乙個更新後超過了len(包括len) 的時候 另乙個即為正解

(4)   進一步的優化,例如:i要移到i+k+1時,如果i+k+1 <= p2的話,可以直接把i移到 j+1,因為,j到j+k已經檢驗過了該字首比以i到i+k之間任何乙個位字首都小;j時的類似,移動到i+1。

這個優化就無需解釋了

至此,求乙個字串的迴圈最小表示在o(n)時間實現,感謝大牛的**。其中實現時的小細節「如果滑動後p1 == p2,將正在變化的那個指標再+1」,開始沒有考慮,害得我想了幾個小時都覺得無法進行正確的移動。具體例題有兩個: 的2006和1729題。乙個是10000規模乙個是100000規模。執行時間前者是0s,後者是0.05s。

上自己醜陋的**

int minimumrepresentation(int *s, int l)  

if(i

模板 字串演算法 字串最小表示法

2014年10月,剛進hdu參加新生賽的時候,就遇到了字串最小表示法的裸題,然而那時什麼都不會的我只得寫暴力,自然tle了。之後在 湖南師範大學第六屆大學生計算機程式設計競賽2b 上,又做到了同樣的裸題。字串演算法 字串最小表示法模板 這是乙個可以用o n 時間解決 字串呈環狀,每一位置都可以作為首...

字串最小表示法

最小表示法的定義 給定乙個字串,不斷地把最後乙個元素移到最前面,可得有n個這樣的字串 稱這n個字串是迴圈同構的 那麼最小表示就是這n個裡面字典序最小的乙個 怎麼求最小表示 wrong 最樸素的方法,把每乙個這樣的字串求出來,然後一一比較,找到字典序最小的迴圈同構串 然後資料範圍變大肯定會超時 那麼正...

字串最小表示法

乙個長度為n的首尾相連的字串可以有n種表示法,例如串 abcd 還可以表示bcda,cdab,dabc當我們面臨這樣的字串的時候,我們很難統計相同字串的個數。因此我們引入一種字串的最小表示法來使這些串變得相同。字串的最小表示法是將原來的字串旋轉得到的字典序最小的串 設字串st的長度為len,我們可以...