You are given a string s and an integer k, 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 <= 105
- 2 <= k <= 104
- s only contains lower case English letters.
这题以前做过, 但是这次提交超时了, 看了看,上次能通过纯属侥幸, 于是换了种方法重新写了一下。
我们创建一个 stack 用来保存入栈的字符和数量, 遍历整个字符串, 对每个字符进行操作, 如果 stack 里处于栈顶的字符跟当前字符相同,则数量加 1, 如果数量达到了 k,则需要弹栈。其他情况直接将当前字符和数量 1 压入栈中即可。
impl Solution {
pub fn remove_duplicates(s: String, k: i32) -> String {
let mut stack: Vec<(char, i32)> = Vec::new();
for c in s.chars() {
if let Some((pc, mut count)) = stack.pop() {
if pc == c {
count += 1;
if count != k {
stack.push((pc, count));
}
continue;
}
stack.push((pc, count));
stack.push((c, 1));
continue;
}
stack.push((c, 1));
}
stack.into_iter().map(|(c, count)| c.to_string().repeat(count as usize)).fold(String::new(), |mut p, s| {
p.push_str(&s);
p
})
}
}