Given a string ‘str’ of digits and an integer ‘n’, build the lowest possible number by removing ‘n’ digits from the string and not changing the order of input digits.
Examples:
Input: str = "4325043", n = 3 Output: "2043" Input: str = "765028321", n = 5 Output: "0221" Input: str = "121198", n = 2 Output: "1118"
The idea is based on the fact that a character among first (n+1) characters must be there in resultant number. So we pick the smallest of first (n+1) digits and put it in result, and recur for remaining characters. Below is complete algorithm.
Initialize result as empty string res = "" buildLowestNumber(str, n, res) 1) If n == 0, then there is nothing to remove. Append the whole 'str' to 'res' and return 2) Let 'len' be length of 'str'. If 'len' is smaller or equal to n, then everything can be removed Append nothing to 'res' and return 3) Find the smallest character among first (n+1) characters of 'str'. Let the index of smallest character be minIndex. Append 'str[minIndex]' to 'res' and recur for substring after minIndex and for n = n-minIndex buildLowestNumber(str[minIndex+1..len-1], n-minIndex).
Below is the implementation of above algorithm.
C++
// C++ program to build the smallest number by removing n digits from // a given number #include<iostream> using namespace std; // A recursive function that removes 'n' characters from 'str' // to store the smallest possible number in 'res' void buildLowestNumberRec(string str, int n, string &res) { // If there are 0 characters to remove from str, // append everything to result if (n == 0) { res.append(str); return ; } int len = str.length(); // If there are more characters to remove than string // length, then append nothing to result if (len <= n) return ; // Find the smallest character among first (n+1) characters // of str. int minIndex = 0; for ( int i = 1; i<=n ; i++) if (str[i] < str[minIndex]) minIndex = i; // Append the smallest character to result res.push_back(str[minIndex]); // substring starting from minIndex+1 to str.length() - 1. string new_str = str.substr(minIndex+1, len-minIndex); // Recur for the above substring and n equals to n-minIndex buildLowestNumberRec(new_str, n-minIndex, res); } // A wrapper over buildLowestNumberRec() string buildLowestNumber(string str, int n) { string res = "" ; // Note that result is passed by reference buildLowestNumberRec(str, n, res); return res; } // Driver program to test above function int main() { string str = "121198" ; int n = 2; cout << buildLowestNumber(str, n); return 0; } |
Java
// Java program to build the smallest number // by removing n digits from a given number class GFG { // class variable is used because Java is // strictly pass by value so "wrapper won't work" // as res is passed by reference static String res = "" ; // A recursive function that removes // 'n' characters from 'str' to store // the smallest possible number in 'res' static void buildLowestNumberRec(String str, int n) { // If there are 0 characters to remove from str, // append everything to result if (n == 0 ) { res.concat(str); return ; } int len = str.length(); // If there are more characters to // remove than string length, // then append nothing to result if (len <= n) return ; // Find the smallest character among // first (n+1) characters of str. int minIndex = 0 ; for ( int i = 1 ; i <= n; i++) if (str.charAt(i) < str.charAt(minIndex)) minIndex = i; // Append the smallest character to result res += str.charAt(minIndex); // substring starting from // minIndex+1 to str.length() - 1. String new_str = str.substring(minIndex + 1 ); // Recur for the above substring // and n equals to n-minIndex buildLowestNumberRec(new_str, n - minIndex); } // Driver Code public static void main(String[] args) { String str = "121198" ; int n = 2 ; buildLowestNumberRec(str, n); System.out.println(res); } } // This code is contributed by // sanjeev2552 |
C#
// C# program to build the smallest number // by removing n digits from a given number using System; class GFG { static String res = "" ; // A recursive function that removes // 'n' characters from 'str' to store // the smallest possible number in 'res' static void buildLowestNumberRec(String str, int n) { // If there are 0 characters to remove from str, // append everything to result if (n == 0) { res += str; return ; } int len = str.Length; // If there are more characters to // remove than string length, // then append nothing to result if (len <= n) return ; // Find the smallest character among // first (n+1) characters of str. int minIndex = 0; for ( int i = 1; i <= n; i++) if (str[i] < str[minIndex]) minIndex = i; // Append the smallest character to result res += str[minIndex]; // substring starting from // minIndex+1 to str.length() - 1. String new_str = str.Substring(minIndex + 1); // Recur for the above substring // and n equals to n-minIndex buildLowestNumberRec(new_str, n - minIndex); } // Driver Code public static void Main(String[] args) { String str = "121198" ; int n = 2; buildLowestNumberRec(str, n); Console.Write(res); } } // This code is contributed by // Rajnis09 |
Output:
1118
Below is an optimised code in C++ contributed by Gaurav Mamgain
// C++ program to build the smallest number by removing // n digits from a given number #include<bits/stdc++.h> using namespace std; void insertInNonDecOrder(deque< char > &dq, char ch) { // if container is empty , insert the current digit if (dq.empty()) dq.push_back(ch); else { char temp = dq.back(); // Keep removing digits larger than current digit // from the back side of deque while ( temp > ch && !dq.empty()) { dq.pop_back(); if (!dq.empty()) temp = dq.back(); } dq.push_back(ch); // insert the current digit } return ; } string buildLowestNumber(string str, int n) { int len = str.length(); // deleting n digits means we need to print k digits int k = len - n; deque< char > dq; string res = "" ; // leaving rightmost k-1 digits we need to choose // minimum digit from rest of the string and print it int i; for (i=0; i<=len-k; i++) // insert new digit from the back side in // appropriate position and/ keep removing // digits larger than current digit insertInNonDecOrder(dq, str[i]); // Now the minimum digit is at front of deque while (i < len) { // keep the minimum digit in output string res += dq.front(); // remove minimum digit dq.pop_front(); // Again insert new digit from the back // side in appropriate position and keep // removing digits larger than current digit insertInNonDecOrder(dq, str[i]); i++; } // Now only one element will be there in the deque res += dq.front(); dq.pop_front(); return res; } // Driver program to test above function int main() { string str = "765028321" ; int n = 5; cout << buildLowestNumber(str, n)<< endl; return 0; } // This code is contributed by Gaurav Mamgain |
Output:
0221
Time Complexity: O(n)
Space Complexity: O(n)
This article is contributed by Pallav Gurha. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.