📌  相关文章
📜  通过执行给定的操作 N 次找到字典最小的字符串

📅  最后修改于: 2022-05-13 01:56:08.701000             🧑  作者: Mango

通过执行给定的操作 N 次找到字典最小的字符串

给定一个包含N个字符的字符串S ,任务是以任意顺序执行以下每个操作N次后,找到最小的字典字符串:

  • 删除S第一个字符并将其插入堆栈X
  • 删除堆栈X的顶部并将其附加到另一个最初为空的字符串Y 的末尾。

例子:

方法:给定的问题可以使用贪心方法来解决。这个想法是执行第一个 操作直到堆栈顶部包含最小字符,之后它可以附加到字符串Y 。这可以通过维护一个后缀数组来有效地完成,其中suff[i]存储后缀的最小 ASCII 值,直到第 i字符。以下是要遵循的步骤:

  • 遍历字符串,根据需要创建后缀数组suff[]
  • 如果堆栈X不为空且suff[i]大于等于堆栈X的顶部字符,则弹出堆栈X的顶部字符并将其附加到字符串Y中。
  • 否则,如果suff[i]等于S[i]附加到字符串Y中。
  • 否则将字符S[i]推入堆栈X

下面是上述方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
 
// Function to find lexicographical smallest
// string by performing the given operations
string smallestString(string S)
{
    // Stores the size of S
    int N = S.size();
 
    // Suffix Array
    int suff[N + 1];
 
    // Initial Condition
    suff[N] = INT_MAX;
 
    // Loop to calculate suffix array
    for (int i = N - 1; i >= 0; i--) {
        suff[i] = min(suff[i + 1], (int)S[i]);
    }
 
    // Initialize the stack X
    // and string y as empty
    stack X;
    string Y = "";
 
    // Loop to traverse string
    for (int i = 0; i < N; i++) {
        // If X is not empty and suff[i]
        // is  greater than equal to top
        // character of stack X
        if (X.size() > 0 && suff[i] >= X.top()) {
            Y += X.top();
            X.pop();
            i--;
        }
 
        // If suff[i] is equal to S[i]
        else if (suff[i] == S[i]) {
            Y += S[i];
        }
 
        // Otherwise push character
        // S[i] into the stack X
        else {
            X.push(S[i]);
        }
    }
 
    // Append all remaining characters
    // of X into string Y
    while (X.size() > 0) {
        Y += X.top();
        X.pop();
    }
 
    // Return Answer
    return Y;
}
 
// Driver Code
int main()
{
    string s = "acdb";
    cout << smallestString(s);
    return 0;
}


Java
// Java program of the above approach
import java.util.*;
class GFG
{
 
  // Function to find lexicographical smallest
  // string by performing the given operations
  public static String smallestString(String S)
  {
 
    // Stores the size of S
    int N = S.length();
 
    // Suffix Array
    int[] suff = new int[N + 1];
 
    // Initial Condition
    suff[N] = Integer.MAX_VALUE;
 
    // Loop to calculate suffix array
    for (int i = N - 1; i >= 0; i--) {
      suff[i]
        = Math.min(suff[i + 1], (int)S.charAt(i));
    }
 
    // Initialize the stack X
    // and string y as empty
    Stack X = new Stack();
    String Y = "";
 
    // Loop to traverse string
    for (int i = 0; i < N; i++)
    {
 
      // If X is not empty and suff[i]
      // is  greater than equal to top
      // character of stack X
      if (X.size() > 0 && suff[i] >= X.peek()) {
        Y += X.peek();
        X.pop();
        i--;
      }
 
      // If suff[i] is equal to S[i]
      else if (suff[i] == S.charAt(i)) {
        Y += S.charAt(i);
      }
 
      // Otherwise push character
      // S[i] into the stack X
      else {
        X.push(S.charAt(i));
      }
    }
 
    // Append all remaining characters
    // of X into string Y
    while (X.size() > 0) {
      Y += X.peek();
      X.pop();
    }
 
    // Return Answer
    return Y;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    String s = "acdb";
    System.out.print(smallestString(s));
  }
}
 
// This code is contributed by Taranpreet


Python3
# Python program of the above approach
import sys
 
# Function to find lexicographical smallest
# string by performing the given operations
def smallestString(S):
 
    # Stores the size of S
    N = len(S)
 
    # Suffix Array
    suff = [0]*(N+1)
 
    # Initial Condition
    suff[N] = sys.maxsize
 
    # Loop to calculate suffix array
    for i in range(N - 1, -2, -1):
        suff[i] = min(suff[i + 1], ord(S[i]))
 
    # Initialize the stack X
    # and string y as empty
    X = []
 
    Y = ""
 
    # Loop to traverse string
    for i in range(0, N):
       
        # If X is not empty and suff[i]
        # is  greater than equal to top
        # character of stack X
        if (len(X) > 0 and suff[i] >= ord(X[-1])):
            Y = Y + X[-1]
            X.pop()
            i = i - 1
 
        # If suff[i] is equal to S[i]
        elif (suff[i] == ord(S[i])):
            Y = Y + S[i]
 
        # Otherwise push character
        # S[i] into the stack X
        else:
            X.append(S[i])
 
    # Append all remaining characters
    # of X into string Y
    while (len(X) > 0):
        Y = Y + X[-1]
        X.pop()
 
    # Return Answer
    return Y
 
# Driver Code
s = "acdb"
print(smallestString(s))
 
# This code is contributed by Taranpreet


C#
// C# program of the above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function to find lexicographical smallest
  // string by performing the given operations
  public static String smallestString(String S)
  {
 
    // Stores the size of S
    int N = S.Length;
 
    // Suffix Array
    int[] suff = new int[N + 1];
 
    // Initial Condition
    suff[N] = int.MaxValue;
 
    // Loop to calculate suffix array
    for (int i = N - 1; i >= 0; i--)
    {
      suff[i]
        = Math.Min(suff[i + 1], (int)S[i]);
    }
 
    // Initialize the stack X
    // and string y as empty
    Stack X = new Stack();
    String Y = "";
 
    // Loop to traverse string
    for (int i = 0; i < N; i++)
    {
 
      // If X is not empty and suff[i]
      // is  greater than equal to top
      // character of stack X
      if (X.Count > 0 && suff[i] >= X.Peek())
      {
        Y += X.Peek();
        X.Pop();
        i--;
      }
 
      // If suff[i] is equal to S[i]
      else if (suff[i] == S[i])
      {
        Y += S[i];
      }
 
      // Otherwise push character
      // S[i] into the stack X
      else
      {
        X.Push(S[i]);
      }
    }
 
    // Append all remaining characters
    // of X into string Y
    while (X.Count > 0)
    {
      Y += X.Peek();
      X.Pop();
    }
 
    // Return Answer
    return Y;
  }
 
  // Driver Code
  public static void Main()
  {
    String s = "acdb";
    Console.Write(smallestString(s));
  }
}
 
// This code is contributed by Saurabh Jaiswal


Javascript



输出
abdc

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