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 the 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 the above algorithm:
C++
#include <bits/stdc++.h>
using namespace std;
string removeKdigits(string num, int k)
{
int n = num.size();
stack< char > mystack;
for ( char c : num) {
while (!mystack.empty() && k > 0
&& mystack.top() > c) {
mystack.pop();
k -= 1;
}
if (!mystack.empty() || c != '0' ){
mystack.push(c);
}
}
while (!mystack.empty() && k--)
mystack.pop();
if (mystack.empty())
return "0" ;
while (!mystack.empty()) {
num[n - 1] = mystack.top();
mystack.pop();
n -= 1;
}
return num.substr(n);
}
int main()
{
string str = "765028321" ;
int k = 5;
cout << removeKdigits(str, k);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static String removeKdigits(String num, int k)
{
StringBuilder result = new StringBuilder();
if (k >= num.length()) {
return "0" ;
}
if (k == 0 ) {
return num;
}
Stack<Character> s = new Stack<Character>();
for ( int i = 0 ; i < num.length(); i++) {
char c = num.charAt(i);
while (!s.isEmpty() && k > 0 && s.peek() > c) {
s.pop();
k--;
}
if (!s.isEmpty() || c != '0' )
s.push(c);
}
while (!s.isEmpty() && k > 0 ) {
k--;
s.pop();
}
if (s.isEmpty())
return "0" ;
while (!s.isEmpty()) {
result.append(s.pop());
}
String str = result.reverse().toString();
return str;
}
public static void main(String[] args)
{
String s = "765028321" ;
int k = 5 ;
System.out.println(removeKdigits(s, 5 ));
}
}
|
Python3
def removeKdigits(num, k):
n = len (num)
mystack = []
for c in num:
while ( len (mystack) > 0 and k > 0 and ord (mystack[ len (mystack) - 1 ]) > ord (c)):
mystack.pop()
k - = 1
if len (mystack) > 0 or c ! = '0' :
mystack.append(c)
while len (mystack) > 0 and k:
mystack.pop()
k - = 1
if len (mystack) = = 0 :
return "0"
num = list (num)
while ( len (mystack) > 0 ):
num[n - 1 ] = mystack[ len (mystack) - 1 ]
mystack.pop()
n - = 1
return "".join(num[n:])
str = "765028321"
k = 5
print (removeKdigits( str , k))
|
C#
using System;
using System.Collections.Generic;
using System.Collections;
class HelloWorld {
static string removeKdigits( string Num, int k)
{
char [] num = Num.ToCharArray();
int n = num.Length;
Stack< char > mystack = new Stack< char >();
for ( int i = 0; i < num.Length; i++) {
while (mystack.Count > 0 && k > 0
&& mystack.Peek() > num[i]) {
mystack.Pop();
k = k - 1;
}
if (mystack.Count > 0 || num[i] != '0' ) {
mystack.Push(num[i]);
}
}
while (mystack.Count > 0 && k > 0) {
mystack.Pop();
k = k - 1;
}
if (mystack.Count == 0)
return "0" ;
while (mystack.Count > 0) {
char temp = mystack.Peek();
num[n - 1] = temp;
mystack.Pop();
n = n - 1;
}
return new string (num).Substring(n);
}
static void Main()
{
string str = "765028321" ;
int k = 5;
Console.WriteLine(removeKdigits(str, k));
}
}
|
Javascript
<script>
function removeKdigits(num,k)
{
let n = num.length;
let mystack = [];
for (let c of num)
{
while (mystack.length>0 && k > 0 &&
mystack[mystack.length-1].charCodeAt(0) > c.charCodeAt(0))
{
mystack.pop();
k -= 1;
}
if (mystack.length > 0 || c !== '0' )
{
mystack.push(c);
}
}
while (mystack.length > 0 && k--)
mystack.pop();
if (mystack.length == 0)
return "0" ;
while (mystack.length > 0)
{
num = num.split( '' );
num[n - 1] = mystack[mystack.length - 1];
num = num.join( '' );
mystack.pop();
n -= 1;
}
return num.substr(n);
}
let str = "765028321"
let k = 5
document.write(removeKdigits(str, k))
</script>
|
- Time Complexity: O(N)
- Space Complexity: O(N)
Below is an optimized code in C++ contributed by Gaurav Mamgain
C++14
#include <bits/stdc++.h>
using namespace std;
void insertInNonDecOrder(deque< char >& dq, char ch)
{
if (dq.empty())
dq.push_back(ch);
else {
char temp = dq.back();
while (temp > ch && !dq.empty()) {
dq.pop_back();
if (!dq.empty())
temp = dq.back();
}
dq.push_back(ch);
}
return ;
}
string buildLowestNumber(string str, int n)
{
int len = str.length();
int k = len - n;
deque< char > dq;
string res = "" ;
int i;
for (i = 0; i <= len - k; i++)
insertInNonDecOrder(dq, str[i]);
while (i < len) {
res += dq.front();
dq.pop_front();
insertInNonDecOrder(dq, str[i]);
i++;
}
res += dq.front();
dq.pop_front();
return res;
}
string lowestNumber(string str, int n)
{
string res = buildLowestNumber(str, n);
string ans = "" ;
int flag = 0;
for ( int i = 0; i < res.length(); i++) {
if (res[i] != '0' || flag == 1) {
flag = 1;
ans += res[i];
}
}
if (ans.length() == 0)
return "0" ;
else
return ans;
}
int main()
{
string str = "765028321" ;
int n = 5;
cout <<lowestNumber(str, n) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static void insertInNonDecOrder(Deque<Character> dq,
char ch)
{
if (dq.isEmpty())
dq.addLast(ch);
else {
char temp = dq.peekLast();
while (temp > ch && !dq.isEmpty()) {
dq.pollLast();
if (!dq.isEmpty())
temp = dq.peekLast();
}
dq.addLast(ch);
}
return ;
}
static String buildLowestNumber(String str, int n)
{
int len = str.length();
int k = len - n;
Deque<Character> dq = new ArrayDeque<>();
String res = "" ;
int i;
for (i = 0 ; i <= len - k; i++)
insertInNonDecOrder(dq, str.charAt(i));
while (i < len) {
res += dq.peekFirst();
dq.pollFirst();
insertInNonDecOrder(dq, str.charAt(i));
i++;
}
res += dq.peekFirst();
dq.pollFirst();
return res;
}
static String lowestNumber(String str, int n)
{
String res = buildLowestNumber(str, n);
String ans = "" ;
int flag = 0 ;
for ( int i = 0 ; i < res.length(); i++) {
if (res.charAt(i) != '0' || flag == 1 ) {
flag = 1 ;
ans += res.charAt(i);
}
}
if (ans.length() == 0 )
return "0" ;
else
return ans;
}
public static void main(String[] args)
{
String str = "765028321" ;
int n = 5 ;
System.out.println(lowestNumber(str, n));
}
}
|
Python3
def insertInNonDecOrder(dq, ch):
if len (dq) = = 0 :
dq.append(ch)
else :
temp = dq[ len (dq) - 1 ]
while (temp > ch and len (dq) > 0 ):
dq.pop( len (dq) - 1 )
if ( len (dq) > 0 ):
temp = dq[ len (dq) - 1 ]
dq.append(ch)
return
def buildLowestNumber( str , n):
length = len ( str )
k = length - n
dq = []
res = ""
i = 0
for i in range (length - k + 1 ):
insertInNonDecOrder(dq, str [i])
i = i + 1
while (i < length):
res = res + dq[ 0 ]
dq.pop( 0 )
insertInNonDecOrder(dq, str [i])
i = i + 1
res = res + dq[ 0 ]
dq.pop( 0 )
return res
def lowestNumber( str , n):
res = buildLowestNumber( str , n)
ans = ""
flag = 0
for i in range ( len (res)):
if res[i] ! = '0' or flag = = 1 :
flag = 1
ans + = res[i]
if len (ans) = = 0 :
return "0"
else :
return ans
str = "765028321"
n = 5
print (lowestNumber( str , n))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void insertInNonDecOrder( ref LinkedList< char > dq,
char ch)
{
if (dq.Count == 0)
dq.AddLast(ch);
else {
char temp = dq.Last.Value;
while (temp > ch && dq.Count > 0) {
dq.RemoveLast();
if (dq.Count > 0)
temp = dq.Last.Value;
}
dq.AddLast(ch);
}
return ;
}
static string buildLowestNumber( string str, int n)
{
int len = str.Length;
int k = len - n;
LinkedList< char > dq = new LinkedList< char >();
string res = "" ;
int i;
for (i = 0; i <= len - k; i++)
insertInNonDecOrder( ref dq, str[i]);
while (i < len) {
res += dq.First.Value;
dq.RemoveFirst();
insertInNonDecOrder( ref dq, str[i]);
i++;
}
res += dq.First.Value;
dq.RemoveFirst();
return res;
}
static string lowestNumber( string str, int n)
{
string res = buildLowestNumber(str, n);
string ans = "" ;
int flag = 0;
for ( int i = 0; i < res.Length; i++) {
if (res[i] != '0' || flag == 1) {
flag = 1;
ans += res[i];
}
}
if (ans.Length == 0)
return "0" ;
else
return ans;
}
public static void Main()
{
string str = "765028321" ;
int n = 5;
Console.WriteLine(lowestNumber(str, n));
}
}
|
Javascript
function insertInNonDecOrder(dq, ch)
{
if (dq.length == 0)
dq.push(ch);
else {
let temp = dq[dq.length - 1];
while (temp > ch && dq.length > 0) {
dq.pop();
if (dq.length > 0)
temp = dq[dq.length - 1];
}
dq.push(ch);
}
return ;
}
function buildLowestNumber(str, n)
{
let len = str.length;
let k = len - n;
let dq = [];
let res = "" ;
let i = 0;
for (i = 0; i <= len - k; i++)
insertInNonDecOrder(dq, str[i]);
while (i < len) {
res = res + dq[0];
dq.shift();
insertInNonDecOrder(dq, str[i]);
i = i + 1;
}
res = res + dq[0];
dq.shift();
return res;
}
function lowestNumber(str, n)
{
let res = buildLowestNumber(str, n);
let ans = "" ;
let flag = 0;
for (let i = 0; i < res.length; i++) {
if (res[i] != '0' || flag == 1) {
flag = 1;
ans += res[i];
}
}
if (ans.length == 0)
return "0" ;
else
return ans;
}
let str = "765028321" ;
let n = 5;
console.log(lowestNumber(str, n));
|
Time Complexity: O(N)
Space Complexity: O(N)
Approach-2:
Let’s suppose the length of the given string num be n.so the result string will contain the length of n-k.
As we proceed to solve this problem we should make sure that the output string contains minimum values at their high weightage positions. so we ensure that by using a stack.
- Return 0 if k >=n. and return num if k=0.
- Create a stack and iterate through num string and push the value at that position if it is greater than the top element of the stack.
- Iterate through the num string and if the integer value at that position is less than the top of the stack we will pop the stack and decrement k until we reach the condition where the top of the stack is less than the value we are looking at(while k>0) (by this we are making sure that most significant positions of the result are filled with minimum values).
- If the k is still greater than 0 we will pop stack until k becomes 0.
- Append the elements in the stack to the result string.
- Delete leading zeroes from the result string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
string removeKdigits(string num, int k)
{
int n = num.size();
stack< char > mystack;
for ( char c : num) {
while (!mystack.empty() && k > 0
&& mystack.top() > c) {
mystack.pop();
k -= 1;
}
if (!mystack.empty() || c != '0' )
mystack.push(c);
}
while (!mystack.empty() && k--)
mystack.pop();
if (mystack.empty())
return "0" ;
while (!mystack.empty()) {
num[n - 1] = mystack.top();
mystack.pop();
n -= 1;
}
return num.substr(n);
}
int main()
{
string str = "765028321" ;
int k = 5;
cout << removeKdigits(str, k);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static String removeKdigits(String num, int k)
{
StringBuilder result = new StringBuilder();
if (k >= num.length()) {
return "0" ;
}
if (k == 0 ) {
return num;
}
Stack<Character> s = new Stack<Character>();
for ( int i = 0 ; i < num.length(); i++) {
char c = num.charAt(i);
while (!s.isEmpty() && k > 0 && s.peek() > c) {
s.pop();
k--;
}
if (!s.isEmpty() || c != '0' )
s.push(c);
}
while (!s.isEmpty() && k > 0 ) {
k--;
s.pop();
}
if (s.isEmpty())
return "0" ;
while (!s.isEmpty()) {
result.append(s.pop());
}
String str = result.reverse().toString();
return str;
}
public static void main(String[] args)
{
String s = "765028321" ;
int k = 5 ;
System.out.println(removeKdigits(s, 5 ));
}
}
|
Python3
def removeKdigits(num, k):
n = len (num)
mystack = []
for c in num:
while ( len (mystack) > 0 and k > 0
and mystack[ - 1 ] > c):
mystack.pop()
k - = 1
if ( len (mystack) > 0 or c ! = '0' ):
mystack.append(c)
while ( len (mystack) > 0 and k):
k - = 1
mystack.pop()
if ( len (mystack) = = 0 ):
return "0"
num = list (num)
while ( len (mystack) > 0 ):
num[n - 1 ] = mystack[ - 1 ]
mystack.pop()
n - = 1
return "".join(num[n:])
Str = "765028321"
k = 5
print (removeKdigits( Str , k))
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static string removeKdigits( string Num, int k){
char [] num = Num.ToCharArray();
int n = num.Length;
Stack< char > mystack = new Stack< char >();
for ( int i = 0; i < num.Length; i++) {
while (mystack.Count > 0 && k > 0 && mystack.Peek() > num[i]) {
mystack.Pop();
k = k - 1;
}
if (mystack.Count > 0 || num[i] != '0' )
mystack.Push(num[i]);
}
while (mystack.Count > 0 && k > 0) {
mystack.Pop();
k = k - 1;
}
if (mystack.Count == 0)
return "0" ;
while (mystack.Count > 0) {
char temp = mystack.Peek();
num[n - 1] = temp;
mystack.Pop();
n = n - 1;
}
return new string (num).Substring(n);
}
public static void Main(){
string str = "765028321" ;
int k = 5;
Console.WriteLine(removeKdigits(str, k));
}
}
|
Javascript
<script>
function removeKdigits(num,k){
let n = num.length
let mystack = []
for (let c of num){
while (mystack.length>0 && k > 0 && mystack[mystack.length - 1] > c){
mystack.pop()
k -= 1
}
if (mystack.length>0 || c != '0' )
mystack.push(c)
}
while (mystack.length>0 && k){
k -= 1
mystack.pop()
}
if (mystack.length == 0)
return "0"
while (mystack.length>0){
num = num.replace(num[n - 1] , mystack[mystack.length-1])
mystack.pop()
n -= 1
}
return num.substring(n,)
}
let Str = "765028321"
let k = 5
document.write(removeKdigits(Str, k))
</script>
|
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.