题意
题解
记录各个字符在字符串中出现的第一次与最后一次的位置,考虑到在字符串中出现的字符必须全部在这个子串中,对于每一个字符,可能需要拓展区间以满足条件。考虑以其第一次出现位置为左界的区间,那么若出现 拓展左界 的情况直接跳过即可,这样可以使得区间去重。问题转化为且不重叠的最大区间数量。贪心地选取可以不重叠的且右界最小的区间即可。
class Solution
{
#define base 26
typedef pair<int, int> P;
public:
int l[base], r[base];
P ps[base];
vector<string> maxNumOfSubstrings(string s)
{
int n = s.length(), k = 0;
memset(l, -1, sizeof(l));
for (int i = 0; i < n; i++)
{
int j = s[i] - 'a';
if (l[j] == -1) l[j] = i;
r[j] = i;
}
for (int i = 0; i < base; i++)
{
if (l[i] == -1)
{
continue;
}
bool f = 0; // 区间是否以 l[i] 为左界
int lb = l[i], ub = r[i];
for (int j = lb + 1; j < ub; j++)
{
if (lb > l[s[j] - 'a'])
{
f = 1;
break;
}
ub = max(ub, r[s[j] - 'a']);
}
if (f) continue;
ps[k++] = P(ub, lb);
}
sort(ps, ps + k);
vector<string> res;
int pre = -1;
for (int i = 0; i < k; i++)
{
if (ps[i].second > pre)
{
pre = ps[i].first;
res.push_back(s.substr(ps[i].second, ps[i].first - ps[i].second + 1));
}
}
return res;
}
};