一、Problem
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.
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"
Constraints:
1 <= s.length <= 10^5
2 <= k <= 10^4
s only contains lower case English letters.
二、Solution
方法一:暴力刪除
- 對於實時 StringBuilder,每一次都去找 k 個相鄰且相同的字符,找到之後使用 delete 刪除。
- 刪除完畢之後更新當前 sb 的長度,到 cur 中,並存儲 cur 到 pre 中
- 如果發現 cur == pre 證明找不到相同的 k 個相鄰字符,返回即可最大長度 max。
class Solution {
public String removeDuplicates(String s, int k) {
StringBuilder sb = new StringBuilder(s);
int cur = -1, pre = 0;
while (cur != pre) {
int cnt = 1;
for (int i = 1; i < sb.length(); i++) {
if (sb.charAt(i-1) != sb.charAt(i))
cnt = 1;
else if (++cnt == k)
sb.delete(i-k+1, i+1);
}
pre = cur;
cur = sb.length();
}
return sb.toString();
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:棧
比賽的時候想用棧來着,賽後寫了下,發現我的棧思路很難對:
- 將字符 c 壓棧前,對比棧頂元素是否和 c 相同,如果是相同的話,那麼計數器 + 1
- 如果計數器到達 k,將棧頂的 k 個元素彈出棧,並將 cnt 設置爲 1
WA:這樣是錯的,這是因爲只用了一個全局的計數器 cnt 導致的。
"deeedbbcccbdaa"
3
預期:"aa"
輸出:"dedbcbda"
class Solution {
public String removeDuplicates(String s, int k) {
Stack<Character> st = new Stack<>();
int cnt = 0;
for (char c : s.toCharArray()) {
if (st.isEmpty() || c != st.peek())
st.push(c);
else {
if (++cnt == k) {
while (cnt-- > 0)
st.pop();
}
cnt = 0;
}
}
StringBuilder sb = new StringBuilder();
while (!st.isEmpty()) {
sb.insert(0, st.pop());
}
return sb.toString();
}
}
正確的棧思路應該對每一個字符進行計數。
class Solution {
public String removeDuplicates(String s, int k) {
Stack<P> st = new Stack<>();
for (char c : s.toCharArray()) {
if (st.isEmpty() || c != st.peek().c)
st.push(new P(c, 1));
else if (++st.peek().cnt == k)
st.pop();
}
StringBuilder sb = new StringBuilder();
while (!st.isEmpty()) {
while (st.peek().cnt-- > 0)
sb.insert(0, st.peek().c);
st.pop();
}
return sb.toString();
}
class P {
char c;
int cnt;
P(char c, int cnt) {this.c = c; this.cnt = cnt;}
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,