Definition
The minimal representation method is used to solve minimal-representation problems for strings.
Minimal Representation of a String
Cyclic Equivalence
If a position is selected in string such that
then and are called cyclically equivalent.
Minimal Representation
The minimal representation of string is the lexicographically smallest string among all strings cyclically equivalent to .
Simple Brute Force
We compare the cyclic equivalents beginning at and each time, denote the position currently being compared by , skip the larger one whenever different characters are encountered, and the one remaining at the end is the optimal answer.
Implementation
C++
int k = 0, i = 0, j = 1;
while (k < n && i < n && j < n) {
if (sec[(i + k) % n] == sec[(j + k) % n]) {
++k;
} else {
if (sec[(i + k) % n] > sec[(j + k) % n])
++i;
else
++j;
k = 0;
if (i == j) i++;
}
}
i = min(i, j);
Python
k, i, j = 0, 0, 1
while k < n and i < n and j < n:
if sec[(i + k) % n] == sec[(j + k) % n]:
k += 1
else:
if sec[(i + k) % n] > sec[(j + k) % n]:
i += 1
else:
j += 1
k = 0
if i == j:
i += 1
i = min(i, j)
Explanation
This implementation performs well on random data, but special data can be constructed to defeat it.
For example, for , it is not difficult to see that the complexity of this algorithm deteriorates to .
When many consecutive repeated substrings occur in the string, this algorithm becomes less efficient, so we consider optimizing this process.
Minimal Representation Method
Core of the Algorithm
Consider a pair of strings whose starting positions in the original string are , respectively, and whose first characters are identical, that is,
First consider the case . We find that no string whose starting-position index satisfies can be the answer. For every string (denoting the string starting at , where ), there is always a string better than it.
Therefore, when comparing, we can skip the indices and directly compare .
Thus, we have completed the optimization of the brute force method above.
Time complexity
Process
- Initialize pointer to and to ; initialize the matching length to .
- Compare the -th characters and jump this pointer according to the comparison result. If the two pointers become equal after the jump, increment either one to ensure that the two strings being compared are different.
- Repeat the above process until the comparison ends.
- The answer is the smaller of .
Implementation
C++
int k = 0, i = 0, j = 1;
while (k < n && i < n && j < n) {
if (sec[(i + k) % n] == sec[(j + k) % n]) {
k++;
} else {
sec[(i + k) % n] > sec[(j + k) % n] ? i = i + k + 1 : j = j + k + 1;
if (i == j) i++;
k = 0;
}
}
i = min(i, j);
Python
k, i, j = 0, 0, 1
while k < n and i < n and j < n:
if sec[(i + k) % n] == sec[(j + k) % n]:
k += 1
else:
if sec[(i + k) % n] > sec[(j + k) % n]:
i = i + k + 1
else:
j = j + k + 1
if i == j:
i += 1
k = 0
i = min(i, j)