最小表示法就是對於乙個迴圈字串,其字典序最小的狀態;
顯然任意乙個迴圈串的最小表示法是唯一的,那麼可以同過比較兩個迴圈串的最小表示法來判斷它們是否相同;
對於樸素演算法:
初始化:i = 0, j = 1, k = 0;
若 s[i] < s[j],j++;
若 s[i] > s[j],i = j, j++;
若 s[i] == s[j],則 k++,直至 s[i + k] != s[j + k]
對於 s[i + k] < s[j + k],j++;
否則 i = j, j++;
返回 min(i, j);
時間複雜度 o(n^2),其中 n 為字串 s 的長度;
**:
1view codeint get_min(string
s)12
if(s[i + k] < s[j + k]) j++;
13else i = j++;14}
15}16return i < j ?i : j;
17 }
優化:s[i + k] != s[j + k]時:
對於 s[i + k] > s[j + k], 可直接令 i += k + 1;
關於其正確性證明:
i += k + 1 可行,只需證明 1) 以 i ~ i + k 中字元為頭首字元的串不可能字典序最小;
證明 1) ,只需證明 2) 對於以 i ~ i + k 開頭,以 i + k 結尾的字尾,一定存在等長的子串字典序比其小;
證明 2): 任取 i <= i' <= i + k,構造子串 s[i', i + k],len = i + k - i' + 1;取與其等長子串 s[j + k - len + 1 , j + k];
顯然有:s[i', i + k - 1] = s[j + k - len + 1, j + k - 1] && s[i + k] > s[j + k],所以 s[i', i + k] > s[j + k - len + 1, j + k];
所以結論 2) 得證,即結論 1) 得證;
對於 s[i + k] < s[j + k],可令 j += k + 1 ;
其正確性證明與上面類似:
j += j + 1 可行,只需證明 1) 以 j ~ j + k 中字元為頭首字元的串不可能字典序最小;
證明 1) ,只需證明 2) 對於以 j ~ j + k 開頭,以 j + k 結尾的字尾,一定存在等長的子串字典序比其小;
證明 2): 任取 j <= j' <= j + k,構造子串 s[j', j + k],len = j + k - j' + 1;取與其等長子串 s[i + k - len + 1 , i + k];
顯然有:s[j', j + k - 1] = s[i + k - len + 1, i + k - 1] && s[j + k] > s[i + k],所以 s[j', j + k] > s[i + k - len + 1, i + k];
所以結論 2) 得證,即結論 1) 得證;
注意:若出現 i == j 的情況,則將 j 往後移一位;
時間複雜度 o(n),其中 n 為字串 s 的長度;
**:
1view codevoid get_min(int n, int m)12}
13 a[n][m] = i < j ?i : j;
14 }
模板 最小表示法
字串的最小表示是該字串的所有迴圈同構串中字典序最小的那個串。根據其迴圈同構結構,採用破環成鏈,即 倍增的形式來表示。引理 若兩個迴圈同構串 s i k 則對於任意的 i in i,i k 均不可能是最優解。證明 s i k 所以對任意的 i in i,i k 有串 s j p 其中 i p j p ...
最大 最小表示法模板
用i 0,j 1,k 0,表示從i開始k長度和從j開始k長度的字串相同 i,j表示當前判斷的位置 當我們str i str j 時,根據上面k的定義,需要進行k 1操作 當str i str j 時,i位置比j位置上字典序要大,固不能使用i作為開頭,又因為i開頭和j開頭的有k個相同的字元,固執行 i...
最小表示法
最小表示法就是找出字串s的的迴圈同構串中字典序最小的乙個。那麼什麼是迴圈同構串呢。是 設s bcad 且s 是s 的迴圈同構的串。s 可以是 bcad 或者cadb,adbc,dbca 即在字串s中從i 0開始,從i迴圈到字串末尾,再從頭迴圈到i,所形成的字元就是s迴圈同構串。因為這樣的同構串不止乙...