Reduce the string by removing K consecutive identical characters
Last Updated : 23 Apr, 2025
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: Using a Stack of Pairs - O(n) time and O(n) space
The approach uses a stack to track characters and their consecutive occurrences. As the string is processed, characters are pushed onto the stack with a count of consecutive occurrences. If a character repeats k
times, it is skipped. After processing, the remaining characters in the stack are used to build the result string, which is then reversed to maintain the correct order.
C++ #include <iostream> #include <stack> #include <string> #include <algorithm> using namespace std; string removeKChar(int k, string str) { if (k == 1) return ""; string ans = ""; stack<pair<char, int>> stk; for (int i = 0; i < str.size(); i++) { if (stk.empty()) { stk.push(make_pair(str[i], 1)); } else { if (str[i] == stk.top().first) { pair<char, int> p = stk.top(); stk.pop(); p.second++; if (p.second < k) stk.push(p); } else { stk.push(make_pair(str[i], 1)); } } } while (!stk.empty()) { if (stk.top().second > 1) { int count = stk.top().second; while (count--) ans += stk.top().first; } else { ans += stk.top().first; } stk.pop(); } reverse(ans.begin(), ans.end()); return ans; } int main() { string s = "geeksforgeeks"; int k = 2; cout << removeKChar(k, s) << "\n"; return 0; }
Java import java.util.*; public class GfG { static String removeKChar(int k, String str) { if (k == 1) return ""; StringBuilder ans = new StringBuilder(); Stack<Pair<Character, Integer>> stk = new Stack<>(); for (char c : str.toCharArray()) { if (stk.isEmpty()) { stk.push(new Pair<>(c, 1)); } else { if (c == stk.peek().getKey()) { Pair<Character, Integer> p = stk.pop(); if (p.getValue() + 1 < k) stk.push(new Pair<>(p.getKey(), p.getValue() + 1)); } else { stk.push(new Pair<>(c, 1)); } } } while (!stk.isEmpty()) { Pair<Character, Integer> top = stk.pop(); for (int i = 0; i < top.getValue(); i++) { ans.append(top.getKey()); } } return ans.reverse().toString(); } public static void main(String[] args) { String s = "geeksforgeeks"; int k = 2; System.out.println(removeKChar(k, s)); } } class Pair<K, V> { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }
Python def removeKChar(k, s): if k == 1: return "" ans = "" stk = [] for char in s: if not stk: stk.append((char, 1)) else: if char == stk[-1][0]: p = stk.pop() if p[1] + 1 < k: stk.append((p[0], p[1] + 1)) else: stk.append((char, 1)) while stk: if stk[-1][1] > 1: count = stk[-1][1] ans += stk[-1][0] * count else: ans += stk[-1][0] stk.pop() return ans[::-1] s = "geeksforgeeks" k = 2 print(removeKChar(k, s))
C# using System; using System.Collections.Generic; using System.Text; class Program { static string removeKChar(int k, string str) { if (k == 1) return ""; StringBuilder ans = new StringBuilder(); Stack<Tuple<char, int>> stk = new Stack<Tuple<char, int>>(); foreach (char c in str) { if (stk.Count == 0) { stk.Push(Tuple.Create(c, 1)); } else { if (c == stk.Peek().Item1) { var p = stk.Pop(); if (p.Item2 + 1 < k) stk.Push(Tuple.Create(p.Item1, p.Item2 + 1)); } else { stk.Push(Tuple.Create(c, 1)); } } } while (stk.Count > 0) { var top = stk.Pop(); ans.Append(top.Item1, top.Item2); } char[] result = ans.ToString().ToCharArray(); Array.Reverse(result); return new string(result); } static void Main() { string s = "geeksforgeeks"; int k = 2; Console.WriteLine(removeKChar(k, s)); } }
JavaScript function removeKChar(k, str) { if (k === 1) return ""; let ans = ""; let stk = []; for (let char of str) { if (stk.length === 0) { stk.push([char, 1]); } else { if (char === stk[stk.length - 1][0]) { let p = stk.pop(); if (p[1] + 1 < k) stk.push([p[0], p[1] + 1]); } else { stk.push([char, 1]); } } } while (stk.length > 0) { let top = stk.pop(); ans += top[0].repeat(top[1]); } return ans.split('').reverse().join(''); } let s = "geeksforgeeks"; let k = 2; console.log(removeKChar(k, s));
Approach: Using a Single Stack - O(n) time and O(n) space
The approach uses a stack to remove consecutive characters that appear exactly k
times. As we iterate through the string, we push each character onto the stack. If the top of the stack matches the current character, we increment a count. When the count reaches k
, the characters are effectively removed. After processing the string, the remaining characters in the stack are popped and concatenated to form the final result.
C++ #include <iostream> #include <stack> #include <string> using namespace std; string removeKChar(int k, string s) { stack<char> st; int i = 0; while (i < s.size()) { char ch = s[i++]; st.push(ch); int count = 0; while (!st.empty() && st.top() == ch) { count++; st.pop(); } if (count == k) continue; else { while (count > 0) { st.push(ch); count--; } } } string result = ""; while (!st.empty()) { result = st.top() + result; st.pop(); } return result; } int main() { int k = 2; string s = "geeksforgeeks"; string ans = removeKChar(k, s); cout << ans << endl; return 0; }
Java import java.util.Stack; public class GfG { public static String removeKChar(int k, String s) { Stack<Character> st = new Stack<>(); int i = 0; while (i < s.length()) { char ch = s.charAt(i++); st.push(ch); int count = 0; while (!st.isEmpty() && st.peek() == ch) { count++; st.pop(); } if (count == k) continue; else { while (count > 0) { st.push(ch); count--; } } } StringBuilder result = new StringBuilder(); while (!st.isEmpty()) { result.insert(0, st.pop()); } return result.toString(); } public static void main(String[] args) { int k = 2; String s = "geeksforgeeks"; String ans = removeKChar(k, s); System.out.println(ans); } }
Python def removeKChar(k, s): stack = [] i = 0 while i < len(s): ch = s[i] stack.append(ch) count = 0 while stack and stack[-1] == ch: count += 1 stack.pop() if count == k: continue else: stack.extend([ch] * count) i += 1 return ''.join(stack) if __name__ == '__main__': k = 2 s = "geeksforgeeks" ans = removeKChar(k, s) print(ans)
C# using System; using System.Collections.Generic; class GfG { public static string RemoveKChar(int k, string s) { Stack<char> stack = new Stack<char>(); int i = 0; while (i < s.Length) { char ch = s[i++]; stack.Push(ch); int count = 0; while (stack.Count > 0 && stack.Peek() == ch) { count++; stack.Pop(); } if (count == k) continue; else { while (count > 0) { stack.Push(ch); count--; } } } char[] result = stack.ToArray(); Array.Reverse(result); return new string(result); } static void Main() { int k = 2; string s = "geeksforgeeks"; string ans = RemoveKChar(k, s); Console.WriteLine(ans); } }
JavaScript function removeKChar(k, s) { let stack = []; let i = 0; while (i < s.length) { let ch = s[i++]; stack.push(ch); let count = 0; while (stack.length > 0 && stack[stack.length - 1] === ch) { count++; stack.pop(); } if (count === k) continue; else { while (count > 0) { stack.push(ch); count--; } } } return stack.join(''); } let k = 2; let s = "geeksforgeeks"; let ans = removeKChar(k, s); console.log(ans);