Lexicographically smallest string possible by using given operations
Last Updated :
06 Feb, 2023
Given a string S consisting of digits from 0 to 9 inclusive, the task is to form the lexicographically smallest string by performing an operation any number of times. In one operation you can choose any position i and delete the digit d at s[i] and insert min(d+1, 9) on any position (at the beginning, at the end, or in between any two adjacent digits).
Examples:
Input: s = “04829”
Output: "02599"
Explanation: Delete 8 and insert 9 at the end of the string, the resulting string is 04299 then delete 4 and insert 5 in the 2nd position of the string. The resulting string is 02599.
Input: s = “07”
Output: "07"
Explanation: Nothing needs to be done here. It is already the lexicographically smallest string we can get.
Approach: To solve the problem follow the below idea:
The idea is to place the smallest digit just before the greater digit in order to form the lexicographically Smallest string. This can be done by iterating from second last digit and if any digit d is found to be greater than its next digit, delete it and insert min (d+1, 9) to the position such that it is smaller than its next digit and greater than its previous digit i.e., string remains in increasing order. We can use priority queue to place the digit to its correct position.
Follow the steps mentioned below to implement the idea:
- Declare the min heap which stores the digit at its correct position.
- Iterate from the second last digit in the reverse direction and if the current digit is found greater than the digit at its next index, delete it
- Insert min (d+1, 9) in the priority queue (min-heap)
- Declare the new string ans to store the resultant string.
- Pop out the top digit from the priority queue until the queue becomes empty and insert it into the resultant string.
- Return the resultant string formed.
Below is the implementation of the above approach:
C++
// C++ Program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;
// Function to obtain lexicographically
// smallest string possible
string smallest_string(string& s, int n)
{
// min heap declaration
priority_queue<int, vector<int>, greater<int> > pq;
int last_digit = s[n - 1] - '0';
pq.push(last_digit);
// Iterating from the last second
// digit in reverse direction
for (int i = n - 2; i >= 0; i--) {
// Digit at current index
int value = s[i] - '0';
// If the digit at current index is
// found greater than its next digit,
// delete it and insert min(d+1, 9)
// to its correct position
if (value > last_digit) {
int mini = min(value + 1, 9);
pq.push(mini);
}
else {
last_digit = value;
pq.push(value);
}
}
// Store the resultant string
string ans = "";
while (!pq.empty()) {
string temp = to_string(pq.top());
ans += temp;
pq.pop();
}
// Returning resultant string
return ans;
}
// Driver code
int main()
{
string s = "04829";
// Length of the string
int n = s.length();
// Function call
cout << smallest_string(s, n) << endl;
s = "07";
n = s.length();
cout << smallest_string(s, n) << endl;
return 0;
}
Java
import java.io.*;
import java.util.*;
import java.util.PriorityQueue;
public class Gfg {
public static String smallestString(String s, int n)
{
PriorityQueue<Integer> pq = new PriorityQueue<>();
int lastDigit = s.charAt(n - 1) - '0';
pq.offer(lastDigit);
for (int i = n - 2; i >= 0; i--) {
int value = s.charAt(i) - '0';
if (value > lastDigit) {
int mini = Math.min(value + 1, 9);
pq.offer(mini);
}
else {
lastDigit = value;
pq.offer(value);
}
}
StringBuilder ans = new StringBuilder();
while (!pq.isEmpty()) {
ans.append(pq.poll());
}
return ans.toString();
}
public static void main(String[] args)
{
String s = "04829";
int n = s.length();
System.out.println(smallestString(s, n));
s = "07";
n = s.length();
System.out.println(smallestString(s, n));
}
}
Python3
import heapq
# Function to obtain lexicographically
# smallest string possible
def smallest_string(s: str, n: int) -> str:
# min heap declaration
pq = []
last_digit = int(s[n - 1])
heapq.heappush(pq, last_digit)
# Iterating from the last second
# digit in reverse direction
for i in range(n - 2, -1, -1):
# Digit at current index
value = int(s[i])
# If the digit at current index is
# found greater than its next digit,
# delete it and insert min(d+1, 9)
# to its correct position
if value > last_digit:
mini = min(value + 1, 9)
heapq.heappush(pq, mini)
else:
last_digit = value
heapq.heappush(pq, value)
# Store the resultant string
ans = ""
while pq:
ans += str(heapq.heappop(pq))
# Returning resultant string
return ans
# Driver code
if __name__ == "__main__":
s = "04829"
# Length of the string
n = len(s)
# Function call
print(smallest_string(s, n))
s = "07"
n = len(s)
print(smallest_string(s, n))
# This code is contributed by divya_p123.
C#
// C# Program to implement the
// above approach
using System;
using System.Linq;
using System.Collections.Generic;
public class GFG {
// Function to obtain lexicographically
// smallest string possible
static string smallest_string(string s, int n)
{
// min heap declaration
SortedSet<int> pq = new SortedSet<int>();
int last_digit = s[n - 1] - '0';
pq.Add(last_digit);
// Iterating from the last second
// digit in reverse direction
for (int i = n - 2; i >= 0; i--) {
// Digit at current index
int value = s[i] - '0';
// If the digit at current index is
// found greater than its next digit,
// delete it and insert min(d+1, 9)
// to its correct position
if (value > last_digit) {
int mini = Math.Min(value + 1, 9);
pq.Add(mini);
}
else {
last_digit = value;
pq.Add(value);
}
}
// Store the resultant string
string ans = "";
foreach(int item in pq) { ans += item; }
if (ans.Length < n) {
for (int i = ans.Length; i < n; i++) {
ans += "9";
}
}
// Returning resultant string
return ans;
}
static public void Main()
{
// Code
string s = "04829";
// Length of the string
int n = s.Length;
// Function call
Console.WriteLine(smallest_string(s, n));
s = "07";
n = s.Length;
Console.WriteLine(smallest_string(s, n));
}
}
// This code is contributed by lokeshmvs21.
JavaScript
//JS Code
// Function to obtain lexicographically
// smallest string possible
function smallest_string(s, n) {
// min heap declaration
let pq = new PriorityQueue({
comparator: (a, b) => a - b
});
let last_digit = s[n - 1] - '0';
pq.enqueue(last_digit);
// Iterating from the last second
// digit in reverse direction
for (let i = n - 2; i >= 0; i--)
{
// Digit at current index
let value = s[i] - '0';
// If the digit at current index is
// found greater than its next digit,
// delete it and insert min(d+1, 9)
// to its correct position
if (value > last_digit) {
let mini = Math.min(value + 1, 9);
pq.enqueue(mini);
} else {
last_digit = value;
pq.enqueue(value);
}
}
// Store the resultant string
let ans = "";
while (!pq.isEmpty()) {
let temp = String(pq.dequeue());
ans += temp;
}
// Returning resultant string
return ans;
}
// Driver code
let s = "04829";
// Length of the string
let n = s.length;
// Function call
console.log(smallest_string(s, n));
s = "07";
n = s.length;
console.log(smallest_string(s, n));
// This code is contributed by ishankhandelwals.
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles:
Similar Reads
Lexicographically smallest string possible by performing K operations on a given string Given a string S of size N and a positive integer K, the task is to perform atmost K operations on string S to make it lexicographically smallest possible. In one operation, swap S[i] and S[j] and then change S[i] to any character, given 1 ? i < j ? N. Examples: Input: S = "geek", K = 5Output: aa
8 min read
Find lexicographical smallest string by performing the given operations N times Given a string S of N characters, the task is to find the smallest lexicographical string after performing each of the following operations N times in any order: Remove the 1st character of S and insert it into a stack X.Remove the top of stack X and append it to the end of another string Y which is
8 min read
Lexicographically smallest string after M operations Given a string S and integer M. The task is to perform exactly M operations to get lexicographical smallest string. In each operation, select one character optimally from the string and update it with immediate next character ( aaa -> aab ), so that string remain lexicographical smallest.Multiple
7 min read
Lexicographically smallest String by pair swapping Suppose you are given a string Str of length N and a set of Pairs ( i, j such that 0 <= i < j < N, 0 based indexing). Pair âi, jâ means that you can swap the ith and jth characters in the string any number of times. You have to output the lexicographically smallest string that can be produc
11 min read
Lexicographically smallest string with given string as prefix Given an array arr[] consisting of N strings and a string S if size M, the task is to find the lexicographically smallest string consisting of the string S as the prefix. If there doesn't exist any string starting with prefix S then print "-1". Examples: Input: arr[] = {"apple", "appe", "apl", "aapl
6 min read