📌  相关文章
📜  在相同奇偶校验索引处最多使用 K 次交换的字典序最大字符串

📅  最后修改于: 2021-10-26 05:22:34             🧑  作者: Mango

给定字符串S和一个正整数K ,任务是使用最多K 次交换找到字典上最大的可能字符串,条件是交换的索引必须是奇数或偶数。

例子:

朴素的方法:朴素的方法是微不足道的。使用贪心算法通过选择当前索引右侧的最大可能字符并与索引的奇偶校验相同,使当前索引从左侧开始最大化(如果当前索引为奇数则为奇数,即使当前指数为偶数)。重复相同的过程最多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 现场工作专业课程学生竞争性编程现场课程