给定长度为N的字符串S,该字符串由小写英文字母和整数K组成。找到在字典上长度为K的最小字符串T,以使其字母集合是S字母集合的子集,而T在字典上大于S注意:字母集是一个集合,而不是多集。例如,abadaba的字母集为{a,b,d}。
例子:
Input : S = “abc”, K = 3
Output : T = “aca”
Explanation: The list of strings T of length 3, such that the set of letters of T is a subset of letters of S is as follows: “aaa”, “aab”, “aac”, “aba”, “abb”, “abc”, “aca”, “acb”, …. Among them, those which are lexicographically greater than “abc”:
“aca”, “acb”, …. Out of those the lexicographically smallest is “aca”.
Input : S = “abc”, K = 2
Output : T = “ac”
一个简单的解决方案是按长度顺序尝试所有长度为k的字符串。对于每个字符串,检查它是否大于S,如果是,则返回它。
以下是解决此问题的有效方法。
让我们考虑两种情况:
1.如果N
2.如果N≥K :在这种情况下,我们需要将字符串S复制到字符串T中(最多K个字符) ,然后对于字符串T,通过反向迭代,我们必须将所有这些字符替换为某个字符,直到字符串T变为在字典上大于字符串S的最小字符串。为此,我们可以执行以下操作:
- 将字符串S的字符存储在STL集中(当然,按排序顺序)
- 将字符串S复制到字符串T(最多K个字符)。
- 反向迭代,找到一个字符(让它在位置“ p”处找到),在该字符集中存在一些具有较大ASCII值的字符。
- 将此字符替换为集合中的字符。
- 将所有字符替换为第(p + 1)个索引到第K个索引之间的最小字符。
插图:令S =“ bcegikmyyy”,N = 10,K =9。设置= {b,c,e,g,i,k,m,y}。将字符串S复制到T,最多K个字符T =“ bcegikmyy”。然后以相反的方向进行迭代,我们首先有“ y”,但集合中没有比“ y”更大的字符,所以继续前进。同样,我们有“ y”,现在继续前进,我们有“ m”,在其中存在更大的字符“ y”。将“ m”替换为“ y”,然后在向前的“ m”之后,将所有字符替换为最小字符,即“ b”。因此,字符串T变为T =“ bcegikybb”;
/* CPP Program to find the lexicographically
smallest string T greater than S whose
letters are subset of letters of S */
#include
using namespace std;
// function to find the lexicographically
// smallest string greater than S
string findString(string S, int N, int K)
{
// stores minimum character
char minChar = 'z';
// stores unique characters of
// string in sorted order
set found;
// Loop through to find the minimum character
// and stores characters in the set
for (int i = 0; i < N; i++) {
found.insert(S[i]);
if (S[i] < minChar)
minChar = S[i];
}
string T;
// Case 1: If N < K
if (N < K) {
// copy the string S upto N characters
T = S;
// append minChar to make the remaining
// characters
for (int i = 0; i < (K - N); i++)
T += minChar;
}
// Case 2 : If N >= K
else {
T = "";
// copy the string S upto K characters
for (int i = 0; i < K; i++)
T += S[i];
int i;
// an iterator to the set
set::iterator it;
// iterating in reverse direction
for (i = K - 1; i >= 0; i--) {
// find the current character in the set
it = found.find(T[i]);
// increment the iterator
it++;
// check if some bigger character exists in set
if (it != found.end())
break;
}
// Replace current character with that found in set
T[i] = *it;
// Replace all characters after with minChar
for (int j = i + 1; j < K; j++)
T[j] = minChar;
}
return T;
}
// Driver Code to test the above function
int main()
{
string S = "abc";
int N = S.length();
// Length of required string
int K = 3;
string T = findString(S, N, K);
cout << "Lexicographically Smallest String "
"greater than " << S
<< " is " << T << endl;
return 0;
}
Lexicographically Smallest String greater than abc is aca
时间复杂度: O(N + K) ,其中N是给定字符串的长度,K是所需字符串的长度。