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

Решение: Каменная игра VII

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

Это является частью серии объяснений решения LeetCode ( index ). Если вам понравилось это решение или нашел его полезным, Пожалуйста, как этот пост и/или УПОТАТЬ Мое решение пост на форумах LeetCode Отказ

Проблема лецкода # 1690 (средний): Каменная игра VII.

Описание:

( Перейти к : Идея решения Код : JavaScript | Python |. Java |. C ++

Алиса и Боб по очереди играют в игру, с Алиса начала первая Отказ

Есть n камни расположены подряд. На ходу каждого игрока они могут Удалить либо самый крайний камень или самый правый камень от ряда и получают точки, равные сумма Из остальных значений камней в ряд. Победитель – это тот, кто с более высоким баллом, когда не осталось камней для удаления.

Боб обнаружил, что он всегда потеряет эту игру (плохой боб, он всегда теряет), поэтому он решил минимизировать разницу . Цель Алисы – максимизировать разницу в счет.

Учитывая массив целых чисел камни где камни [я] представляет значение i камень слева , вернуть Разница в счет Алисы и Боба, если они оба играют Оптимально Отказ

Примеры:

Вход: камни = [5,3,1,4,2]
Вывод: 6
Объяснение: – Алиса удаляет 2 и получает 5 + 3 + 1 + очки. ,, камни = [5,3,1,4]. – Боб удаляет 5 и получает 3 + 1 + очки. ,, камни = [3,1,4]. – Алиса удаляет 3 и получает 1 + очки. ,, камни = [1,4]. – Боб снимает 1 и получает 4 очка. ,, камни = [4]. – Алиса удаляет 4 и получает 0 баллов. ,, камни = []. Разница на счет составляет 18 -.
Вход: камни = [7,90,5,1,100,10,10,2]
Вывод: 122

Ограничения:

  • N.Length
  • 2
  • 1 [я]

Идея:

( Перейти к : Описание проблемы Код : JavaScript | Python |. Java |. C ++

Как и большинство проблем с каменной игрой, этот сводится к системе постоянно повторяющихся подбпроблем, так как существует множество различных способов добраться до того же состояния платы, что и к концу игры. Это естественно указывает на Динамическое программирование ( DP ) Решение.

Для того, чтобы представлять различные позиции на доске, мы обычно построим N * n DP Matrix, где N Это длина массива камней ( S ). В этом массиве DP DP [I] [J] будет представлять лучшие результаты разницы с Я представляя левый оставшийся индекс камня и J представляя самый правый оставшийся указатель камня.

Мы начнем в Я – 2 и итереть назад и начать каждый вложенный для петля на J + 1 Отказ Это гарантирует, что мы наращиваем пирамиду результатов DP вниз, всегда начинаем каждую строку с i и J рядом друг с другом.

Для каждой строки мы отслеживаем сумму Всего из камней в диапазоне [я, j] Добавляя S [j] На каждой итерации j . Затем мы можем представлять идеальную игру «текущий проигрыватель», выбрав наилучшее значение между выбором камня на i ( Total – S [I] ) и выбирая камень на j ( Всего – s [j] ). Для каждого варианта мы должны также вычесть наилучшее значение, которое другой игрок получит из полученной позиции платы ( DP [I + 1] [J] или DP [I] [J-1] ).

Поскольку мы будем строить только с ячейки влево и над текущей ячейкой, однако, мы можем фактически устранить матрицу DP и вместо этого только один массив, представляющий текущую строку, использующую ее каждый раз. Это бросит Космическая сложность от O (n ^ 2) к O (n) Отказ

Этот подход работает, потому что при оценке новой клетки ячейка к левой части уже будет перезаписана и будет точно представлять предыдущую ячейку на том же строке. Недостаточно перезаписанное текущее значение до сих пор представляет ячейку, которая была бы в строке выше в полной матрице DP.

В конце решение будет значение, хранящимся в массиве DP, представляющей положение платы со всеми присутствующими камнями. Поэтому мы должны Вернуть DP [N-1] Отказ

  • Сложность времени: O (N ^ 2) где N это длина S
  • Космическая сложность: O (n) за дп

Код JavaScript:

( Перейти к : Описание проблемы Идея решения

var stoneGameVII = function(S) {
    let N = S.length, dp = new Uint32Array(N)
    for (let i = N - 2; ~i; i--) {
        let total = S[i]
        for (let j = i + 1; j < N; j++) {
            total += S[j]
            dp[j] = Math.max(total - S[i] - dp[j], total - S[j] - dp[j-1])
        }
    }
    return dp[N-1]
};

Код Python:

( Перейти к : Описание проблемы Идея решения

class Solution:
    def stoneGameVII(self, S: List[int]) -> int:
        N, dp = len(S), [0] * len(S)
        for i in range(N - 2, -1, -1):
            total = S[i]
            for j in range(i + 1, N):
                total += S[j]
                dp[j] = max(total - S[i] - dp[j], total - S[j] - dp[j-1])
        return dp[-1]

Java код:

( Перейти к : Описание проблемы Идея решения

class Solution {
    public int stoneGameVII(int[] S) {
        int N = S.length;
        int[] dp = new int[N];
        for (int i = N - 2; i >= 0; i--) {
            int total = S[i];
            for (int j = i + 1; j < N; j++) {
                total += S[j];
                dp[j] = Math.max(total - S[i] - dp[j], total - S[j] - dp[j-1]);
            }
        }
        return dp[N-1];
    }
}

C ++ код:

( Перейти к : Описание проблемы Идея решения

class Solution {
public:
    int stoneGameVII(vector& S) {
        int N = S.size();
        vector dp(N);
        for (int i = N - 2; ~i; i--) {
            int total = S[i];
            for (int j = i + 1; j < N; j++) {
                total += S[j];
                dp[j] = max(total - S[i] - dp[j], total - S[j] - dp[j-1]);
            }
        }
        return dp[N-1];
    }
};

Оригинал: “https://dev.to/seanpgallivan/solution-stone-game-vii-3lei”