# Remove All Adjacent Duplicates in String II

Given a string s, a k duplicate removal consists of choosing k adjacent and equal letters from s and removing them causing the left and the right side of the deleted substring to concatenate together.

We repeatedly make k duplicate removals on s until we no longer can.

Return the final string after all such duplicate removals have been made.

It is guaranteed that the answer is unique.

Example 1:

```Input: s = "abcd", k = 2
Output: "abcd"
Explanation: There's nothing to delete.```
Example 2:

```Input: s = "deeedbbcccbdaa", k = 3
Output: "aa"
Explanation:
First delete "eee" and "ccc", get "ddbbbdaa"
Then delete "bbb", get "dddaa"
Finally delete "ddd", get "aa"```
Example 3:

```Input: s = "pbbcggttciiippooaais", k = 2
Output: "ps"
```

Constraints:

• 1 <= s.length <= 10^5
• 2 <= k <= 10^4
• s only contains lower case English letters.

Solution:

```class Solution {
static class Node {
char c;
int count;

public Node(char c) {
this.c = c;
this.count = 1;
}
}

public String removeDuplicates(String s, int k) {
Deque<Node> stack = new ArrayDeque();
for (char c : s.toCharArray()) {
if (stack.isEmpty() || stack.peekFirst().c != c) {
stack.push(new Node(c));
} else {
Node top = stack.peekFirst();
if (top.count == k - 1) {
stack.pop();
} else {
top.count ++;
}
}
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
Node node = stack.pop();
for (int i = 0; i < node.count; i ++) {
sb.append(node.c);
}
}
return sb.reverse().toString();
}
}```