Это можно сделать за O (n) время.
Идея заключается в том, чтобы предсказать конец каждой подстроки. Мы знаем, что если мы читаем символ, то последнее вхождение этого символа должно быть в той же подстроке, что и есть (в противном случае в двух различных подстроках будет повторный символ).
Давайте использовать abbacacd
как пример. Предположим, мы знаем первое и последнее вхождения каждого символа в строке.
01234567
abbacacd (reading a at index 0)
- we know that our substring must be at least abbaca (last occurrence of a);
- the end of our substring will be the maximum between the last occurrence of
all the chars inside the own substring;
- we iterate through the substring:
012345 (we found b at index 1)
abbaca substring_end = maximum(5, last occurrence of b = 2)
substring_end = 5.
012345 (we found b at index 2)
abbaca substring_end = maximum(5, last occurrence of b = 2)
substring_end = 5.
012345 (we found a at index 3)
abbaca substring_end = maximum(5, last occurrence of a = 5)
substring_end = 5.
012345 (we found c at index 4)
abbaca substring_end = maximum(5, last occurrence of c = 6)
substring_end = 6.
0123456 (we found a at index 5)
abbacac substring_end = maximum(6, last occurrence of a = 5)
substring_end = 6.
0123456 (we found c at index 6)
abbacac substring_end = maximum(6, last occurrence of c = 6)
substring_end = 6.
---END OF FIRST SUBSTRING---
01234567
abbacacd [reading d]
- the first and last occurrence of d is the same index.
- d is an atomic substring.
Решение O (n):
#include <bits/stdc++.h>
using namespace std;
int main(){
int pos[26][2];
int index;
memset(pos, -1, sizeof(pos));
string s = "aaabbcccddda";
for(int i = 0; i < s.size(); i++){
index = s[i] - 'a';
if(pos[index][0] == -1) pos[index][0] = i;
pos[index][1] = i;
}
int substr_end;
for(int i = 0; i < s.size(); i++){
index = s[i] - 'a';
if(pos[index][0] == pos[index][1]) cout<<s[i]<<endl;
else{
substr_end = pos[index][1];
for(int j = i + 1; j < substr_end; j++){
substr_end = max(substr_end, pos[s[j] - 'a'][1]);
}
cout<<s.substr(i, substr_end - i + 1)<<endl;
i = substr_end;
}
}
}