给定字符串S和一个正整数K ,任务是使用最多K 次交换找到字典上最大的可能字符串,条件是交换的索引必须是奇数或偶数。
例子:
Input: S = “ancqz”, K = 2
Output: “zqcna“
Explanation: In one swap, we can swap characters ‘n’ and ‘q’ as they both are at even indices (2 and 4 assuming 1-based indexing). The string becomes “aqcnz”. In the second swap we can swap characters ‘a’ and ‘z’ as both have odd indices. The final string “zqcna” is the largest lexicographically possible using 2 swap operations.
Note: We cannot swap for instance ‘a’ and ‘n’ or ‘n’ and ‘z’ as one of them would be at an odd index while the other at even index.
Input: S = “geeksforgeeks”, K = 3
Output: “sreksfoegeekg“
朴素的方法:朴素的方法是微不足道的。使用贪心算法通过选择当前索引右侧的最大可能字符并与索引的奇偶校验相同,使当前索引从左侧开始最大化(如果当前索引为奇数则为奇数,即使当前指数为偶数)。重复相同的过程最多K次。该方法的时间复杂度为O(N 2 ) 。
高效的方法:可以使用优先级队列改进上述方法。请按照以下步骤解决问题:
- 创建两个优先级队列,一个用于奇数索引字符,另一个用于偶数索引字符。
- 遍历字符串中的字符,如果连索引字符自带然后搜索比当前指数和字符比其持有连字符的优先级队列当前字符更大更大的索引。如果有的话,交换两个字符推送当前字符和我们在优先级队列中找到的索引。
- 当奇数字符出现时,将遵循相同的程序。
- 如果K变为0 ,则终止循环。
- 结果字符串将是答案。
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function which returns
// the largest possible string
string lexicographicallyLargest(string S, int K)
{
// Finding length of the string
int n = S.length();
// Creating two priority queues of pairs
// for odd and even indices separately
priority_queue > pqOdd, pqEven;
// Storing all possible even
// indexed values as pairs
for (int i = 2; i < n; i = i + 2) {
// Stores pair as {character, index}
pqEven.push(make_pair(S[i], i));
}
// Storing all possible odd indexed
// values as pairs
for (int i = 3; i < n; i = i + 2) {
// Stores pair as {character, index}
pqOdd.push(make_pair(S[i], i));
}
for (int i = 0; i < n; i++) {
// For even indices
if (i % 2 == 0) {
// Removing pairs which
// cannot be used further
while (!pqEven.empty()
and pqEven.top().second <= i)
pqEven.pop();
// If a pair is found whose index comes after
// the current index and its character is
// greater than the current character
if (!pqEven.empty()
and pqEven.top().first > S[i]) {
// Swap the current index with index of
// maximum found character next to it
swap(S[i], S[pqEven.top().second]);
int idx = pqEven.top().second;
pqEven.pop();
// Push the updated character at idx index
pqEven.push({ S[idx], idx });
K--;
}
}
// For odd indices
else {
// Removing pairs which cannot
// be used further
while (!pqOdd.empty()
and pqOdd.top().second <= i)
pqOdd.pop();
// If a pair is found whose index comes after
// the current index and its character is
// greater than the current character
if (!pqOdd.empty()
and pqOdd.top().first > S[i]) {
// Swap the current index with index of
// maximum found character next to it
swap(S[i], S[pqOdd.top().second]);
int idx = pqOdd.top().second;
pqOdd.pop();
// Push the updated character at idx index
pqOdd.push({ S[idx], idx });
K--;
}
}
// Breaking out of the loop if K=0
if (K == 0)
break;
}
return S;
}
// Driver Code
int main()
{
// Input
string S = "geeksforgeeks";
int K = 2;
// Function Call
cout << lexicographicallyLargest(S, K);
return 0;
}
sreksfoegeekg
时间复杂度: O(NlogN)
辅助空间: 在)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。