Open In App

Lexicographically smallest string possible by using given operations

Last Updated : 06 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.


Output

02599
07

Time Complexity: O(N)
Auxiliary Space: O(N)

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads