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);