Reduce the string by removing K consecutive identical characters

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 = “w3wiki” 
Output: gksforgks 
Explanation: After removal of both occurrences of the substring “ee”, the string reduces to “gksforgks”.

Input: K = 3, str = “qddxxxd” 
Output:
Explanation: 
Removal of “xxx” modifies the string to “qddd”. 
Again, removal of “ddd”modifies the string to “q”. 

Recommended Practice

Approach: This problem can be solved using the Stack data structure. Follow the steps below to solve the problem:

Below is the implementation of the above approach: 

C++
// 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) {
                    pair<char, int> P = stk.top();
                    stk.pop();
                    P.second++;
                    if (P.second == k)
                        continue;
                    else
                        stk.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
                    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()) {
            if (stk.top().second > 1) {
                // if Frequency of current character greater
                // than 1(let m),then append that character
                // m times in output string
                int count = stk.top().second;
                while (count--)
                    output += stk.top().first;
            }
            else {
                output += stk.top().first;
            }
            stk.pop();
        }
        reverse(output.begin(), output.end());
        return output;
    }
};

// Driver Code
int main()
{

    string s = "w3wiki";
    int k = 2;
    Solution obj;
    cout << obj.remove_k_char(k, s) << "\n";

    return 0;
}

// This Code has been contributed by shubhamm050402
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char ch;
    int freq;
} Pair;

Pair createPair(char ch, int freq)
{
    Pair p;
    p.ch = ch;
    p.freq = freq;
    return p;
}

void push(Pair* stack, int* top, char ch, int freq)
{
    Pair p = createPair(ch, freq);
    stack[++(*top)] = p;
}

Pair pop(Pair* stack, int* top) { return stack[(*top)--]; }

char* remove_k_char(int k, char* s)
{
    if (k == 1)
        return "";

    Pair stack[strlen(s)];
    int top = -1;

    for (int i = 0; i < strlen(s); i++) {
        if (top == -1 || stack[top].ch != s[i])
            push(stack, &top, s[i], 1);
        else {
            stack[top].freq++;
            if (stack[top].freq == k)
                pop(stack, &top);
        }
    }

    int resultLength = top + 1;
    char* result
        = (char*)malloc((resultLength + 1) * sizeof(char));

    for (int i = 0; i < resultLength; i++)
        result[i] = stack[i].ch;

    result[resultLength] = '\0';
    return result;
}

int main()
{
    char s[] = "w3wiki";
    int k = 2;

    char* result = remove_k_char(k, s);
    printf("%s\n", result);

    free(result);

    return 0;
}
Java
// Java implementation of the approach
import java.util.*;

class GFG {

    // Function to find the reduced string
    public static String reduced_String(int k, String s)
    {

        // Base Case
        if (k == 1) {
            // all elements remove,send empty string
            return "";
        }

        // 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 {
                st.push(new Pair(s.charAt(i), 1));
            }
        }

        // iterate through the stack
        // append characters in String

        StringBuilder output = new StringBuilder();

        while (st.size() > 0) {
            char c = st.peek().c;
            int cnt = st.peek().ctr;
            // If frequency of a character is cnt, then
            // append that character to cnt times in String
            while (cnt-- > 0)
                output.append(String.valueOf(c));
            st.pop();
        }
        output.reverse();
        return output.toString();
    }

    // Driver code
    public static void main(String[] args)
    {
        int k = 2;
        String st = "w3wiki";
        String ans = reduced_String(k, st);
        System.out.println(ans);
    }

    // Pair Class
    static class Pair {
        char c;
        int ctr;
        Pair(char c, int ctr)
        {
            this.c = c;
            this.ctr = ctr;
        }
    }
}

// This Code has been contributed by shubhamm050402
Python
# Python3 implementation of the approach

# Pair class to store character and freq
class 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 code
if __name__ == "__main__":
    
    k = 2
    s = "w3wiki"
    obj = Solution()
    print(obj.reduced_String(k,s))

    # This code is contributed by chantya17.
C#
// C# implementation of the above approach
using 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 = "w3wiki";
        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
Javascript
<script>
// Javascript implementation of the approach

class Pair
{
    constructor(c,ctr)
    {
        this.c = c;
            this.ctr = ctr;
    }
}

// Function to find the reduced string
function 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 code
let k = 2;
let st = "w3wiki";
let ans = reduced_String(k, st);
document.write(ans+"<br>");

// This code is contributed by rag2127
</script>

Output
gksforgks

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

ANOTHER METHOD:

APPROACH:

  1. First we declare a Stack<Character> to store each character of the string.
  2. Then we iterate over the string.
  3. While iterating we keep a counter variable and keep pushing the character in the stack and poping simultaneously until we get a counter equals k, that implies we have got the sequence of character to remove from the string.
  4. At last we declare a String Builder to concatenate the characters from the stack.

Implementation:

C++
#include <bits/stdc++.h>
using namespace std;

string reduced_String(int k, string s) {
    stack<char> stk;
    int i = 0;
    while (i < s.length()) {
        char ch = s[i++];
        stk.push(ch);
        int count = 0;
        while (!stk.empty() && stk.top() == ch) {
            count++;
            stk.pop();
        }
        if (count == k)
            continue;
        else {
            while (count > 0) {
                stk.push(ch);
                count--;
            }
        }
    }
    string result = "";
    while (!stk.empty()) {
        result = stk.top() + result;
        stk.pop();
    }
    return result;
}

int main() {
    int k = 2;
    string st = "w3wiki";
    string ans = reduced_String(k, st);
    cout << ans << endl;
    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 100

// Function to remove k consecutive characters from the
// string
char* reduced_String(int k, char* s)
{
    char stk[MAX_SIZE]; // Stack to store characters
    int top = -1; // Top index of stack
    int i = 0;

    while (s[i] != '\0') {
        char ch = s[i++];
        stk[++top] = ch;

        int count = 0;
        while (top >= k - 1 && stk[top] == ch) {
            count++;
            top--;
        }

        if (count == k)
            continue;
        else {
            while (count > 0) {
                stk[++top] = ch;
                count--;
            }
        }
    }

    char* result = (char*)malloc(
        (top + 2)
        * sizeof(char)); // Allocate memory for the result

    int resultIndex = 0;
    while (top >= 0) {
        result[resultIndex++] = stk[top];
        top--;
    }
    result[resultIndex]
        = '\0'; // Null-terminate the result string

    return result;
}

// Driver code
int main()
{
    int k = 2;
    char st[] = "skgrofskg";

    char* ans = reduced_String(k, st);
    printf("%s\n", ans);

    free(ans); // Free the memory allocated for the result

    return 0;
}
Java
import java.io.*;
import java.util.*;

class GFG {
  public static String reduced_String(int k, String s)
  {
      // Your code goes here
      Stack<Character> stk = new Stack<Character>();
      int i = 0;
      while (i < s.length()) {
          char ch = s.charAt(i++);
          stk.push(ch);
          int count = 0;
          while ((stk.size() > 0) && (stk.peek() == ch)) {
              count++;
              stk.pop();
          }
          if (count == k)
              continue;
          else {
              while (count > 0) {
                  stk.push(ch);
                  count--;
              }
          }
      }
      StringBuilder sb = new StringBuilder();
      for (char ch : stk)
          sb = sb.append(ch);
      return sb.toString();
  }
      public static void main(String[] args)
      {
          int k = 2;
          String st = "w3wiki";
          String ans = reduced_String(k, st);
          System.out.println(ans);
      }
  }
//This code is contributed by Raunak Singh
Python
class Program:

    # Function to reduce the string
    @staticmethod
    def reduced_string(k, s):
        # Creating an empty stack to hold characters
        stk = []
        i = 0

        # Loop through each character of the input string
        while i < len(s):
            ch = s[i]
            i += 1
            stk.append(ch)

            count = 0

            # Count the number of consecutive occurrences of current character
            while len(stk) > 0 and stk[-1] == ch:
                count += 1
                stk.pop()

            # If the count is equal to k, skip to the next character
            if count == k:
                continue
            else:
                # Otherwise, push back the characters that were popped
                while count > 0:
                    stk.append(ch)
                    count -= 1

        # Build the final reduced string by popping all characters from the stack
        result = ""
        while len(stk) > 0:
            result = stk.pop() + result

        return result


# Driver Code
def main():
    k = 2
    st = "w3wiki"

    ans = Program.reduced_string(k, st)

    print(ans)


if __name__ == "__main__":
    main()
C#
// Importing required libraries
using System;
using System.Collections.Generic;

class Program {

    // Function to reduce the string
    static string ReducedString(int k, string s)
    {

        // Creating an empty stack
        // to hold characters
        Stack<char> stk = new Stack<char>();
        int i = 0;

        // Loop through each character
        // of the input string
        while (i < s.Length) {
            char ch = s[i++];
            stk.Push(ch);

            int count = 0;

            // Count the number of consecutive
            // occurrences of  current character
            while (stk.Count > 0 && stk.Peek() == ch) {
                count++;
                stk.Pop();
            }

            // If the count is equal to k,
            // skip to the next character
            if (count == k)
                continue;
            else {

                // Otherwise, push back the
                // characters that were popped
                while (count > 0) {
                    stk.Push(ch);
                    count--;
                }
            }
        }

        // Build the final reduced string
        // by popping all characters
        // from the stack
        string result = "";
        while (stk.Count > 0) {
            result = stk.Pop() + result;
        }

        return result;
    }

    // Driver Code
    static void Main(string[] args)
    {
        int k = 2;
        string st = "w3wiki";

        string ans = ReducedString(k, st);

        Console.WriteLine(ans);
    }
}
Javascript
// Function to reduce the string
function reducedString(k, s) {
// Creating an empty stack to hold characters
  const stk = [];
  let i = 0;

// Loop through each character of the input string
   while (i < s.length) {
   const ch = s[i++];
   stk.push(ch);

   let count = 0;

// Count the number of consecutive occurrences of current character
while (stk.length > 0 && stk[stk.length - 1] === ch) {
  count++;
  stk.pop();
}

// If the count is equal to k, skip to the next character
if (count === k) {
  continue;
} else {
  // Otherwise, push back the characters that were popped
  while (count > 0) {
    stk.push(ch);
    count--;
  }
}
}

// Build the final reduced string by popping all characters from the stack
 let result = "";
 while (stk.length > 0) {
 result = stk.pop() + result;
}

return result;
}

// Driver Code
const k = 2;
const st = "w3wiki";
const ans = reducedString(k, st);
console.log(ans);

Output
gksforgks

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


ANOTHER METHOD:

Approach:

1)Iterate through the string: Start iterating through the string character by character.

2)Identify consecutive identical characters: While iterating, keep track of consecutive identical characters and count their occurrences.

3)Remove consecutive identical characters when count reaches K: When the count of consecutive identical characters reaches K, skip adding them to the result string.

4)Concatenate non-consecutive identical characters: If the count is less than K, concatenate the characters to the result string.

5)Continue until the end of the string: Repeat steps 2-4 until the end of the string is reached.

6)Return the reduced string: Return the final result string.

C++
#include <iostream>
#include <string>

using namespace std;

string solve(string s, int k) {
    string ans = "";
    for (int i = 0; i < s.size(); i++) {
        int j = i;
        string temp = "";
        while (j < s.size() && s[i] == s[j]) {
            temp += s[i];
            j++;
        }
        if (j - i != k)
            ans += temp;
        i = j - 1;
    }
    return ans;
}

int main() {
    int k;
    string str;

    // Input
    cout << "Enter the string: ";
    cin >> str;
    cout << "Enter the value of K: ";
    cin >> k;

    // Function call
    string reducedString = solve(str, k);

    // Output
    cout << "Reduced string: " << reducedString << endl;

    return 0;
}

Time Complexity:

The time complexity of this approach is O(N), where N is the length of the input string.

Auxiliary Space: O(N)

Space Complexity:

The space complexity of this approach is O(1).



Contact Us