通过执行给定的操作 N 次找到字典最小的字符串
给定一个包含N个字符的字符串S ,任务是以任意顺序执行以下每个操作N次后,找到最小的字典字符串:
- 删除S的第一个字符并将其插入堆栈X 。
- 删除堆栈X的顶部并将其附加到另一个最初为空的字符串Y 的末尾。
例子:
Input: S = “cab”
Output: abc
Explanation: The given string can be obtained using the following operations:
- Perform operation 1. Hence, S = “ab”, X = “c”, Y = “”.
- Perform operation 1. Hence, S = “b”, X = “ca”, Y = “”.
- Perform operation 2. Hence, S = “b”, X = “c”, Y = “a”.
- Perform operation 1. Hence, S = “”, X = “cb”, Y = “a”.
- Perform operation 2. Hence, S = “”, X = “c”, Y = “ab”.
- Perform operation 2. Hence, S = “”, X = “”, Y = “abc”.
Now, each of the given operations is performed N times and the string obtained is “abc” which is the smallest possible.
Input: S = “acdb”
Output: abdc
方法:给定的问题可以使用贪心方法来解决。这个想法是执行第一个 操作直到堆栈顶部包含最小字符,之后它可以附加到字符串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)