給定乙個字串 s[1~n] , 如果我們不斷的把它的最後乙個字元放到開頭,最終會得到 n 個字串, 稱這 n 個字串是迴圈同構的。這些字串中字典序最小的稱為 字串 s 的最小表示 。
例如 "abca" , 它的4個迴圈同構字串為 "abca" , "aabc" , "caab" , "bcaa" . s 的最小表示是 "aabc" .因為乙個與 s 迴圈同構的字串可以用該字串在s 中的起始下標來表示,所以我們就用 b[i] 來表示 從 i 開始的迴圈同構字串 , 即 s[i~n] + s[1 ~ i-1 ] 。
如何求出乙個字串的最小表示 ? 最樸素的方法就是依次比較 這 n 個迴圈同構字串 ,找出字典序最小的乙個 . 比較兩個迴圈同構字串 b[i] 和 b[j] 時,我們採用的是直接向後掃瞄的方式. 依次取 k = 0,1 ,2 .. . ., 比較 b[i+k] 和 b[ j +k] 是否相等 ,直到找到乙個不相等的位置,從而確定出 b[i] 和 b[j] 的大小關係 .
實際上,乙個字串的最小表示可以在o(n) 的線性時間內求出 . 我們首先把 s 字串複製乙份接在它的尾端,得到 ss.
顯然 b[i] = ss[i ~ i+n-1 ] 從 i 開始的 n 個字元 .
s = "bacacabc" ,i =2 , j =4 , k =3 下標1
2345
6789
1011
1213
1415
1617
ii+kba
caca
bcba
caca
bcjj+kba
caca
bcba
caca
bc如果在 i + k 與 j +k 處發現不相等 , 假設 ss[i+k] > ss[j+k] ,那麼當然可以知道 b[i] 不是最小表示(因為存在乙個更小的迴圈同構字串 b[j] ) .除此之外 , 我們還可以 b[i+1] , b[i+2] ... b[i+k] 也都不是最小表示,因為對於 1<=p <=k ,存在乙個比b[i+p]更小的迴圈同構串b[j+p ] , b[i+p] > b[j+p] ;
同理如果 ss[i+k ] 最小表示演算法
1 初始化 i = 1 , j = 2 ;
2 通過直接向後掃瞄方法, 比較 b[i] 與 b[j] 兩個迴圈同構串.
(1) 如果掃瞄了 n 個字串仍然相等, 說明 s 只由一種字元構成 . 任意 b[i] 都是 它的最小表示.
(2) 如果在 i+k 與 j + k 處發現不相等 .
如果 ss[i+k] >ss[j+k] 令 i = i+k+1 , 若此時i = j , 則令 i = i+1
如果 ss[ i +k] 3 如果 i > n , b[j] 為最小表示 , j > n ,b[i] 為最小表示. 否則重複第二步
#include #include #include #include #define swap(a,b) a ^= b ^= a ^= b
int main()
int i = 1 , j = 2 , k ;
while(i<=n & j<=n )
else
}int ans = min(i,j) ; // b[ans] 為最小表示
for(int i = ans ; i <= ans+n -1 ; i++)
return 0 ;
}
最小表示法
最小表示法就是找出字串s的的迴圈同構串中字典序最小的乙個。那麼什麼是迴圈同構串呢。是 設s bcad 且s 是s 的迴圈同構的串。s 可以是 bcad 或者cadb,adbc,dbca 即在字串s中從i 0開始,從i迴圈到字串末尾,再從頭迴圈到i,所形成的字元就是s迴圈同構串。因為這樣的同構串不止乙...
最小表示法
最小表示法 思想 在字串迴圈同構問題中的應用 摘自周源的ppt 前言 最小表示法 比起動態規劃 貪心等思想,在當今競賽中似乎並不是很常見。但是在解決判斷 同構 一類問題中卻起著重要的作用。本文即將討論字串中的同構問題,如何巧妙地運用最小表示法來解題呢,讓我們繼續一起思考吧。到底什麼是迴圈同構的字串呢...
最小表示法
最小表示法與kmp演算法一樣都可以解決字串匹配問題,但效率更高,短,作用更大。最小表示法就是乙個字串的最小字典序。怎麼求乙個字串的最小字典序呢?首先將這個字串擴充套件一倍 建設存在d陣列裡 然後我們用三個指標i 0,j 1,k 0,來尋找最小字典序的開頭字母,為了優於kmp,我們要做到o n i表示...