Reduce the string by removing K consecutive identical characters - GeeksforGeeks

29 Nov, 2021
Given a string str and an integer K, the task is to reduce the string by applying the following operation any number of times until it is no longer possible:
Choose a group of K consecutive identical characters and remove them from the string.
Finally, print the reduced string.
Examples:  
Input: K = 2, str = “geeksforgeeks” Output: gksforgks Explanation: After removal of both occurrences of the substring “ee”, the string reduces to “gksforgks”.
Input: K = 3, str = “qddxxxd” Output: q Explanation: Removal of “xxx” modifies the string to “qddd”. Again, removal of “ddd”modifies the string to “q”. 
Approach: This problem can be solved using the Stack data structure. Follow the steps below to solve the problem:
Initialize a stack of pair<char, int>, to store characters and their respective consecutive frequencies.
Iterate over the characters of the string.
If the current character is different from the character present currently at the top of the stack, then set its frequency to 1.
Otherwise, if the current character is the same as the character at the top of the stack, then increase its frequency by 1.
If the frequency of the character at the top of the stack is K, pop that out of the stack.
Finally, print the characters which are remaining in the stack as the resultant string.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// CPP program for the above approach#include <bits/stdc++.h>#include <iostream>using namespace std; // Basic Approach is to create a Stack that store the// Character and its continuous repetition number This is// done using pair<char,int> Further we check at each// iteration, whether the character matches the top of stack// if it does then check for number of repetitions// else add to top of stack with count 1 class Solution {public:    string remove_k_char(int k, string s)    {         // Base Case        // If k=1 then all characters        // can be removed at each        // instance        if (k == 1)            return "";        // initialize string        string output = "";         // create a stack using pair<> for storing each        // character and corresponding        // repetition        stack<pair<char, int> > stk;         // iterate through the string        for (int i = 0; i < s.length(); i++) {             // if stack is empty then simply add the            // character with count 1 else check if            // character is same as top of stack            if (stk.empty() == true) {                stk.push(make_pair(s[i], 1));            }            else {                 // if character at top of stack is same as                // current character increase the number of                // repetitions in the top of stack by 1                if (s[i] == (stk.top()).first) {                    stk.push(                        { s[i], stk.top().second + 1 });                    if (stk.top().second == k) {                        int x = k;                        while (x) {                            stk.pop();                            x--;                        }                    }                }                else {                     // if character at top of stack is not                    // same as current character push the                    // character along with count 1 into the                    // top of stack                    stk.push(make_pair(s[i], 1));                }            }        }         // Iterate through the stack        // Use string(int,char) in order to replicate the        // character multiple times and convert into string        // then add in front of output string        while (!stk.empty()) {            output += stk.top().first;            stk.pop();        }        reverse(output.begin(), output.end());        return output;    }}; // Driver Codeint main(){     string s = "geeksforgeeks";    int k  = 2;    Solution obj;    cout << obj.remove_k_char(k, s) << "\n";     return 0;} // This code has been contributed by Navansh Goel
// Java implementation of the approachimport java.util.*; class GFG {     // Function to find the reduced string    public static String reduced_String(int k, String s)    {        // Base Case        if (k == 1) {            String ans = "";            return ans;        }         // Creating a stack of type Pair        Stack<Pair> st = new Stack<Pair>();         // Length of the string S        int l = s.length();        int ctr = 0;         // iterate through the string        for (int i = 0; i < l; i++) {             // if stack is empty then simply add the            // character with count 1 else check if            // character is same as top of stack            if (st.size() == 0) {                st.push(new Pair(s.charAt(i), 1));                continue;            }             // if character at top of stack is same as            // current character increase the number of            // repetitions in the top of stack by 1            if (st.peek().c == s.charAt(i)) {                Pair p = st.peek();                st.pop();                p.ctr += 1;                if (p.ctr == k) {                    continue;                }                else {                    st.push(p);                }            }            else {                 // if character at top of stack is not                // same as current character push the                // character along with count 1 into the                // top of stack                st.push(new Pair(s.charAt(i), 1));            }        }         // iterate through the stack        // Use string(int,char) in order to replicate the        // character multiple times and convert into string        // then add in front of output string        String ans = "";        while (st.size() > 0) {            char c = st.peek().c;            int cnt = st.peek().ctr;            while (cnt-- > 0)                ans = c + ans;            st.pop();        }        return ans;    }     // Driver code    public static void main(String[] args)    {        int k = 2;        String st = "geeksforgeeks";        String ans = reduced_String(k, st);        System.out.println(ans);    }     static class Pair {        char c;        int ctr;        Pair(char c, int ctr)        {            this.c = c;            this.ctr = ctr;        }    }}
# Python3 implementation of the approach # Pair class to store character and freqclass Pair:    def __init__(self,c ,ctr):        self.c= c        self.ctr = ctr class Solution:         # Function to find the reduced string    def reduced_String(self , k , s):                 #Base Case        if (k == 1):            return ""         # Creating a stack of type Pair        st = []             # iterate through given string        for i in range(len(s)):                         # if stack is empty then simply add the            # character with count 1 else check if            # character is same as top of stack            if (len(st) == 0):                st.append((Pair(s[i] , 1)))                continue                                          # if character at top of stack is same as            # current character increase the number of            # repetitions in the top of stack by 1            if (st[-1].c == s[i]):                                 pair = st.pop()                pair.ctr +=1                                 if (pair.ctr == k):                    continue                                 else:                    st.append(pair)                              else:                                 # if character at top of stack is not                # same as current character push the                # character along with count 1 into the                # top of stack                st.append((Pair(s[i] , 1)))                  # Iterate through the stack        # Use string(int,char) in order to replicate the        # character multiple times and convert into string        # then add in front of output string        ans = ""        while(len(st) > 0):                         c = st[-1].c            cnt = st[-1].ctr                         while(cnt >0):                ans  = c + ans                cnt -= 1                         st.pop()                 return (ans) # Driver codeif __name__ == "__main__":         k = 2    s = "geeksforgeeks"    obj = Solution()    print(obj.reduced_String(k,s))     # This code is contributed by chantya17.
// C# implementation of the above approachusing System;using System.Collections.Generic;public class GFG {     // Function to find the reduced string    public static String reduced_String(int k, String s)    {        // Base Case        if (k == 1) {                         return "";        }         // Creating a stack of type Pair        Stack<Pair> st = new Stack<Pair>();         // Length of the string S        int l = s.Length;              // iterate through the string        for (int i = 0; i < l; i++) {             // if stack is empty then simply add the            // character with count 1 else check if            // character is same as top of stack            if (st.Count == 0) {                st.Push(new Pair(s[i], 1));                continue;            }             // if character at top of stack is same as            // current character increase the number of            // repetitions in the top of stack by 1            if (st.Peek().c == s[i]) {                Pair p = st.Peek();                st.Pop();                p.ctr += 1;                if (p.ctr == k) {                    continue;                }                else {                    st.Push(p);                }            }            else {                 // if character at top of stack is not                // same as current character push the                // character along with count 1 into the                // top of stack                st.Push(new Pair(s[i], 1));            }        }         // iterate through the stack        // Use string(int,char) in order to replicate the        // character multiple times and convert into string        // then add in front of output string        String ans = "";        while (st.Count > 0) {            char c = st.Peek().c;            int cnt = st.Peek().ctr;            while (cnt-- > 0)                ans = c + ans;            st.Pop();        }        return ans;    }     // Driver code    public static void Main(String[] args)    {        int k = 2;        String st = "geeksforgeeks";        String ans = reduced_String(k, st);        Console.Write(ans);    }     public class Pair {        public char c;        public int ctr;        public Pair(char c, int ctr)        {            this.c = c;            this.ctr = ctr;        }    }}// This code has been contributed by 29AjayKumar
<script>// Javascript implementation of the approach class Pair{    constructor(c,ctr)    {        this.c = c;            this.ctr = ctr;    }} // Function to find the reduced stringfunction reduced_String(k,s){    // Base Case        if (k == 1) {            let ans = "";            return ans;        }          // Creating a stack of type Pair        let st = [];          // Length of the string S        let l = s.length;        let ctr = 0;          // iterate through the string        for (let i = 0; i < l; i++) {              // if stack is empty then simply add the            // character with count 1 else check if            // character is same as top of stack            if (st.length == 0) {                st.push(new Pair(s[i], 1));                continue;            }              // if character at top of stack is same as            // current character increase the number of            // repetitions in the top of stack by 1            if (st[st.length-1].c == s[i]) {                let p = st[st.length-1];                st.pop();                p.ctr += 1;                if (p.ctr == k) {                    continue;                }                else {                    st.push(p);                }            }            else {                  // if character at top of stack is not                // same as current character push the                // character along with count 1 into the                // top of stack                st.push(new Pair(s[i], 1));            }        }          // iterate through the stack        // Use string(int,char) in order to replicate the        // character multiple times and convert into string        // then add in front of output string        let ans = "";        while (st.length > 0) {            let c = st[st.length-1].c;            let cnt = st[st.length-1].ctr;            while (cnt-- > 0)                ans = c + ans;            st.pop();        }        return ans;} // Driver codelet k = 2;let st = "geeksforgeeks";let ans = reduced_String(k, st);document.write(ans+"<br>"); // This code is contributed by rag2127</script>
gksforgks
Time Complexity: O(N) Auxiliary Space: O(N)
imdhruvgupta
29AjayKumar
Akanksha_Rai
navanshgoel
UtkarshPandey6
simmytarika5
rag2127
tejendrapratap
amartyaniel20
chantya17
surinderdawra388
Competitive Programming
Hash
Stack
Strings
Hash
Strings
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Prefix Sum Array - Implementation and Applications in Competitive Programming
Ordered Set and GNU C++ PBDS
Multistage Graph (Shortest Path)
7 Best Coding Challenge Websites in 2020
What is Competitive Programming and How to Prepare for It?
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)
Hashing | Set 2 (Separate Chaining)