最小表示法的定義:
給定乙個字串,不斷地把最後乙個元素移到最前面,可得有n個這樣的字串(稱這n個字串是迴圈同構的),那麼最小表示就是這n個裡面字典序最小的乙個;
怎麼求最小表示:
wrong :最樸素的方法,把每乙個這樣的字串求出來,然後一一比較,找到字典序最小的迴圈同構串;然後資料範圍變大肯定會超時;
那麼正解:
o(n);
pre:用b[i]來表示以i開頭的迴圈同構串;
1、首先把s複製一遍加到s的後面,可以看出b[i ~ i + n - 1] == s[i ~ i + n -1];
我們用兩個指標來模擬比較:i = 1, j = 2;假設比較過程中,b[i + k] > b[j + k], 那麼說明b[i]對應的迴圈同構串不是最小表示;因為存在b[j]小於b[i], 還可以推出從b[i + 1] ~ b[i + k] 都不是最小表示;因為總會有 b[i + p] < b[j + p], 0 <= p <= k; (此時的i為i + 1 到 i + k的其中的任何乙個值)那麼就可以跳過這些值;
所以,如何求最小表示;
pre: 把s複製一遍加到s的後面
1、初始化兩個指標 i = 1, j = 2;
2、通過直接向後掃瞄的方法,比較b[i] 與b[j]兩個迴圈同構串;
那麼就會產生三種情況:
1、掃瞄了n個後,s[i]始終等於s[j],那麼說明這個字串由一種字元構成;
2、如果s[i + k] > s[i + j],證明 j 對應的迴圈同構串比 i 對應的迴圈同構串要小,那麼i就要向後移,由前面的推倒,i = i + k + 1;這時要再判斷 i 是否等於 j ,如果等於 j,證明將要比較的是兩個相同字串,那麼 i++;
同理,如果 j 對應的迴圈同構串比 i 對應的迴圈同構串要大,就反過來,移動 j;
如果 i 大於 n;b[j] 為最小表示,如果 j 大於 n;那麼b[i] 為最小表示;
void min_show()
else
} ans = min(i, j);
}
字串最小表示法
乙個長度為n的首尾相連的字串可以有n種表示法,例如串 abcd 還可以表示bcda,cdab,dabc當我們面臨這樣的字串的時候,我們很難統計相同字串的個數。因此我們引入一種字串的最小表示法來使這些串變得相同。字串的最小表示法是將原來的字串旋轉得到的字典序最小的串 設字串st的長度為len,我們可以...
字串最小表示法 O(n 演算法
網上看了這篇文章後還是感覺有些地方講的沒有詳細的證明所以新增了一點 紅色字是博主寫的 求字串的迴圈最小表示 上面說的兩個字串同構的,並沒有直接先求出min s 而是通過指標移動,當某次匹配串長時,那個位置就是min s 而這裡的問題就是 不是給定兩個串,而是給出乙個串,求它的min s eg min...
字串的最小表示法
定義 給定乙個字串 s 1 n 如果我們不斷把他的最後乙個字元放到開頭,最終會得到 n 個字串,稱這 n 個字串是迴圈同構的。這些字串中字典序最小的乙個,稱為字串 s 的最小表示。例如 s abca 那麼它的 4 個迴圈同構字串為 abca aabc caab bcaa s 的最小表示為 aabc ...