Решения LeetCode (161 часть серии)
Это является частью серии объяснений решения LeetCode ( index ). Если вам понравилось это решение или нашел его полезным, Пожалуйста, как этот пост и/или УПОТАТЬ Мое решение пост на форумах LeetCode Отказ
Проблема лецкода # 1209 (средний): удалить все смежные дубликаты в строке II
Описание:
( Перейти к : Идея решения Код : JavaScript | Python |. Java |. C ++
Учитывая строку с , а к Дублирующее удаление состоит из выбора к соседний а также равные буквы от S и удаление их, вызывающих левую и правую сторону удаленной подстроки для объединения вместе.
Мы неоднократно делаем к Дублирующие удаления на S пока мы больше не можем.
Верните последнюю строку после того, как все такие дублирующие удаления были сделаны.
Гарантируется, что ответ уникален.
Примеры:
| Вход: | |
| Выход: | “ABCD” |
| Объяснение: | Нечего удалить. |
| Вход: | |
| Выход: | “АА” |
| Объяснение: | Сначала удалите «Eee» и «CCC», получите «DDBBBDAA», затем удалите «BBB», получите «DDDAA», наконец, удалите «DDD», получите «AA» |
| Вход: | |
| Выход: | “PS” |
Ограничения:
1. Длина ^ 5.2^4SСодержит только строчные буквы английского языка.
Идея:
( Перейти к : Описание проблемы Код : JavaScript | Python |. Java |. C ++
( Перейти к : Описание проблемы Идея решения
(Примечание. Это часть серии пояснений серии INEATCODE. Если вам нравится это решение или найти его полезным, Пожалуйста, Upvote эта почта.)
Идея:
Всякий раз, когда мы должны повторять тип данных и удалить потенциально вложенную информацию, естественная мысль – использовать какой-то куча или рекурсивный Решение для отслеживания данных гнездования во время поиска наших матчей.
В наивном рекурсивном решении мы можем искать матч шаблона, отслеживая текущий Считать соседних дубликатов, затем рекурсивно вызывают основную функцию снова на строке с удаленным шаблоном. Это решение неоднократно итарает через большую часть строки, но иначе имеет низкий накладной расход, поэтому он имеет тенденцию быть конкурентоспособным, особенно для более коротких строк.
В попытке достичь более эффективного решения для более длинных струн, мы можем вместо этого использовать стек для создания нашего ответа. Чтобы не допустить возвращения до последнего К Элементы нашего стека после удаления совпадения мы можем поддерживать отдельный стек ( st ), именно специально для указателей значения запуска каждого дубликата.
Чтобы сохранить в пространстве, мы также можем использовать Встроенный стек Подход к массиву CHAR ( SC ), образованный из входной строки ( S ), а не использовать отдельный стек. Для этого мы можем использовать Двухкомнациональная система в котором один указатель ( I ) отслеживает конец находящегося на месте «стека», а другой указатель ( j ), итерат через Сюжет как обычно.
Как мы двигаемся J через Сюжет мы пишем в «стек», перезаписывая SC [I] с SC [J] . Когда мы хотим удалить К элементы из «стека», мы просто двигаемся Я вернуться K . Затем, как только мы закончим, мы можем вернуть «стек», который является первой частью SC через i .
Это решение имеет больше накладных расходов, но не повторяется как можно больше итераций, поэтому он должен быть более эффективным для более длинных строк.
Реализация:
Один только C ++ имеет смежные строки и не требуют S быть разделенным в массив CHAR перед обработкой как Встроенный стек Отказ
Код JavaScript:
( Перейти к : Описание проблемы Идея решения
с рекурсией:
var removeDuplicates = function(S, K) {
for (let i = 1, count = 1; i < S.length; i++) {
S.charAt(i) === S.charAt(i-1) ? count++ : count = 1
if (count === K)
S = removeDuplicates(S.slice(0, i-K+1) + S.slice(i+1), K);
}
return S
};
С стеком в месте:
var removeDuplicates = function(S, K) {
let SC = S.split(""), st = [0], i, j
for (i = 1, j = 1; j < S.length; SC[++i] = SC[++j]) {
if (SC[i] !== SC[i-1]) st.push(i)
else if (i - st[st.length-1] + 1 === K) i = st.pop()-1
}
return SC.slice(0,i+1).join("")
};
Код Python:
( Перейти к : Описание проблемы Идея решения
с рекурсией:
class Solution:
def removeDuplicates(self, S: str, K: int) -> str:
count, i = 1, 1
while i < len(S):
if S[i] == S[i-1]: count += 1
else: count = 1
if count == K: S = self.removeDuplicates(S[:i-K+1] + S[i+1:], K)
i += 1
return S
С стеком в месте:
class Solution:
def removeDuplicates(self, S: str, K: int) -> str:
SC, st, i, j = list(S), [0], 1, 1
while j < len(S):
SC[i] = SC[j]
if i == 0 or SC[i] != SC[i-1]: st.append(i)
elif i - st[-1] + 1 == K: i = st.pop() - 1
i += 1
j += 1
return "".join(SC[:i])
Java код:
( Перейти к : Описание проблемы Идея решения
с рекурсией:
class Solution {
public String removeDuplicates(String S, int K) {
for (int i = 1, count = 1; i < S.length(); i++) {
count = S.charAt(i) == S.charAt(i-1) ? count + 1 : 1;
if (count == K)
S = removeDuplicates(S.substring(0, i-K+1) + S.substring(i+1), K);
}
return S;
}
}
С стеком в месте:
class Solution {
public String removeDuplicates(String S, int K) {
char[] SC = S.toCharArray();
int i, j;
Stack st = new Stack<>();
st.add(0);
for (i = 1, j = 1; j < S.length(); i++, j++) {
char chr = SC[i] = SC[j];
if (i == 0 || chr != SC[i-1]) st.add(i);
else if (i - st.peek() + 1 == K) i = st.pop() - 1;
}
return new String(SC, 0, i);
}
}
C ++ код:
( Перейти к : Описание проблемы Идея решения
с рекурсией:
class Solution {
public:
string removeDuplicates(string S, int K) {
for (int i = 1, count = 1; i < S.size(); i++) {
count = S[i] == S[i-1] ? count + 1 : 1;
if (count == K)
S = removeDuplicates(S.substr(0, i-K+1) + S.substr(i+1), K);
}
return S;
}
};
С стеком в месте:
class Solution {
public:
string removeDuplicates(string S, int K) {
int i, j;
stack st;
st.push(0);
for (i = 1, j = 1; j < S.size(); i++, j++) {
S[i] = S[j];
if (i == 0 || S[i] != S[i-1]) st.push(i);
else if (i - st.top() + 1 == K) {
i = st.top() - 1;
st.pop();
}
}
return S.substr(0, i);
}
};
Решения LeetCode (161 часть серии)
Оригинал: “https://dev.to/seanpgallivan/solution-remove-all-adjacent-duplicates-in-string-ii-431f”