📌  相关文章
📜  在最多一次交换中查找字典序最小的字符串

📅  最后修改于: 2021-10-26 06:56:03             🧑  作者: Mango

给定一个长度为N的字符串str 。任务是在最多只允许一次交换时找出字典序最小的字符串。也就是说,可以选择和交换两个索引1 <= i, j <= n 。此操作最多可进行一次。

例子:

方法:我们的想法是使用排序并计算给定字符串的最小辞书字符串可能。计算完排序后的字符串,从给定的字符串找出第一个不匹配的字符,并用排序后的字符串最后一次出现的不匹配字符替换它。

例如,让 str = “geeks” 和 sorted = “eegks”。第一个不匹配的字符放在首位。这和字符来交换,使得这个字符与排序字符串的字符相匹配。结果字典序最小的字符串。将“g”替换为最后出现的“e”后,该字符串将成为字典序最小的 eegks。

下面是上述方法的实现:

C++
// C++ implementation of the above approach
#include 
using namespace std;
 
// Function to return the lexicographically
// smallest string that can be formed by
// swapping at most one character.
// The characters might not necessarily
// be adjacent.
string findSmallest(string s)
{
    int len = s.size();
 
    // Store last occurrence of every character
    int loccur[26];
 
    // Set -1 as default for every character.
    memset(loccur, -1, sizeof(loccur));
 
    for (int i = len - 1; i >= 0; --i) {
 
        // Character index to fill
        // in the last occurrence array
        int chI = s[i] - 'a';
        if (loccur[chI] == -1) {
 
            // If this is true then this
            // character is being visited
            // for the first time from the last
            // Thus last occurrence of this
            // character is stored in this index
            loccur[chI] = i;
        }
    }
 
    string sorted_s = s;
    sort(sorted_s.begin(), sorted_s.end());
 
    for (int i = 0; i < len; ++i) {
        if (s[i] != sorted_s[i]) {
 
            // Character to replace
            int chI = sorted_s[i] - 'a';
 
            // Find the last occurrence
            // of this character.
            int last_occ = loccur[chI];
 
            // Swap this with the last occurrence
            swap(s[i], s[last_occ]);
            break;
        }
    }
 
    return s;
}
 
// Driver code
int main()
{
    string s = "geeks";
    cout << findSmallest(s);
    return 0;
}


Java
// Java implementation of the above approach
import java.util.*;
 
class GFG{
  
// Function to return the lexicographically
// smallest String that can be formed by
// swapping at most one character.
// The characters might not necessarily
// be adjacent.
static String findSmallest(char []s)
{
    int len = s.length;
  
    // Store last occurrence of every character
    int []loccur = new int[26];
  
    // Set -1 as default for every character.
    Arrays.fill(loccur, -1);
  
    for (int i = len - 1; i >= 0; --i) {
  
        // Character index to fill
        // in the last occurrence array
        int chI = s[i] - 'a';
        if (loccur[chI] == -1) {
  
            // If this is true then this
            // character is being visited
            // for the first time from the last
            // Thus last occurrence of this
            // character is stored in this index
            loccur[chI] = i;
        }
    }
  
    char []sorted_s = s;
    Arrays.sort(sorted_s);
  
    for (int i = 0; i < len; ++i) {
        if (s[i] != sorted_s[i]) {
  
            // Character to replace
            int chI = sorted_s[i] - 'a';
  
            // Find the last occurrence
            // of this character.
            int last_occ = loccur[chI];
  
            // Swap this with the last occurrence
            char temp = s[last_occ];
            s[last_occ] = s[i];
            s[i] = temp;
            break;
        }
    }
  
    return String.valueOf(s);
}
  
// Driver code
public static void main(String[] args)
{
    String s = "geeks";
    System.out.print(findSmallest(s.toCharArray()));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the above approach
 
# Function to return the lexicographically
# smallest string that can be formed by
# swapping at most one character.
# The characters might not necessarily
# be adjacent.
def findSmallest(s) :
 
    length = len(s);
 
    # Store last occurrence of every character
    # Set -1 as default for every character.
    loccur = [-1]*26;
 
 
    for i in range(length - 1, -1, -1) :
 
        # Character index to fill
        # in the last occurrence array
        chI = ord(s[i]) - ord('a');
        if (loccur[chI] == -1) :
 
            # If this is true then this
            # character is being visited
            # for the first time from the last
            # Thus last occurrence of this
            # character is stored in this index
            loccur[chI] = i;
 
    sorted_s = s;
    sorted_s.sort();
 
    for i in range(length) :
        if (s[i] != sorted_s[i]) :
 
            # Character to replace
            chI = ord(sorted_s[i]) - ord('a');
 
            # Find the last occurrence
            # of this character.
            last_occ = loccur[chI];
 
            # Swap this with the last occurrence
            # swap(s[i], s[last_occ]);
            s[i],s[last_occ] = s[last_occ],s[i]
            break;
 
    return "".join(s);
 
# Driver code
if __name__ == "__main__" :
 
    s = "geeks";
     
    print(findSmallest(list(s)));
 
# This code is contributed by Yash_R


C#
// C# implementation of the above approach
using System;
 
class GFG{
   
// Function to return the lexicographically
// smallest String that can be formed by
// swapping at most one character.
// The characters might not necessarily
// be adjacent.
static String findSmallest(char []s)
{
    int len = s.Length;
   
    // Store last occurrence of every character
    int []loccur = new int[26];
   
    // Set -1 as default for every character.
    for (int i = 0; i < 26; i++)
        loccur[i] = -1;
   
    for (int i = len - 1; i >= 0; --i) {
   
        // char index to fill
        // in the last occurrence array
        int chI = s[i] - 'a';
        if (loccur[chI] == -1) {
   
            // If this is true then this
            // character is being visited
            // for the first time from the last
            // Thus last occurrence of this
            // character is stored in this index
            loccur[chI] = i;
        }
    }
   
    char []sorted_s = s;
    Array.Sort(sorted_s);
   
    for (int i = 0; i < len; ++i) {
        if (s[i] != sorted_s[i]) {
   
            // char to replace
            int chI = sorted_s[i] - 'a';
   
            // Find the last occurrence
            // of this character.
            int last_occ = loccur[chI];
   
            // Swap this with the last occurrence
            char temp = s[last_occ];
            s[last_occ] = s[i];
            s[i] = temp;
            break;
        }
    }
   
    return String.Join("", s);
}
   
// Driver code
public static void Main(String[] args)
{
    String s = "geeks";
    Console.Write(findSmallest(s.ToCharArray()));
}
}
 
// This code is contributed by sapnasingh4991


Javascript


输出:
eegks

时间复杂度: O(N)
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程