Lexicographically smallest string possible by using given operations
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. |
02599 07
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles:
- Introduction to Strings – Data Structure and Algorithm Tutorials
- What is Priority Queue | Introduction to Priority Queue
Please Login to comment...