Рубрики
Без рубрики

Решение: удалить все смежные дубликаты в строке II

Это является частью серии пояснений решения LeetCode (индекс). Если вам понравилось это решение или Фу … помечены алгоритмами, JavaScript, Java, Python.

Решения 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^4
  • S Содержит только строчные буквы английского языка.

Идея:

( Перейти к : Описание проблемы Код : 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”