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

📅  最后修改于: 2021-04-29 13:35:44             🧑  作者: 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


输出:
eegks