Skip to main content

Stone Game III - Solution & Explanation

HardArrayMathDynamic ProgrammingGame Theory17 min readAsked at: Meta, Google
Practice this problem

Problem Statement

Alice and Bob continue their games with piles of stones. There are several stones arranged in a row, and each stone has an associated value which is an integer given in the array stoneValue.

Alice and Bob take turns, with Alice starting first. On each player's turn, that player can take 1, 2, or 3 stones from the first remaining stones in the row.

The score of each player is the sum of the values of the stones taken. The score of each player is 0 initially.

The objective of the game is to end with the highest score, and the winner is the player with the highest score and there could be a tie. The game continues until all the stones have been taken.

Assume Alice and Bob play optimally.

Return "Alice" if Alice will win, "Bob" if Bob will win, or "Tie" if they will end the game with the same score.

 

Example 1:

Input: stoneValue = [1,2,3,7]
Output: "Bob"
Explanation: Alice will always lose. Her best move will be to take three piles and the score become 6. Now the score of Bob is 7 and Bob wins.

Example 2:

Input: stoneValue = [1,2,3,-9]
Output: "Alice"
Explanation: Alice must choose all the three piles at the first move to win and leave Bob with negative score.
If Alice chooses one pile her score will be 1 and the next move Bob's score becomes 5. In the next move, Alice will take the pile with value = -9 and lose.
If Alice chooses two piles her score will be 3 and the next move Bob's score becomes 3. In the next move, Alice will take the pile with value = -9 and also lose.
Remember that both play optimally so here Alice will choose the scenario that makes her win.

Example 3:

Input: stoneValue = [1,2,3,6]
Output: "Tie"
Explanation: Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise she will lose.

 

Constraints:

  • 1 <= stoneValue.length <= 5 * 104
  • -1000 <= stoneValue[i] <= 1000

Approach Overview

Problem Overview: You receive an integer array stoneValue. Alice and Bob take turns picking 1 to 3 stones from the start of the array. Each player adds the picked values to their score and both play optimally. The task is to determine whether Alice wins, Bob wins, or the game ends in a tie.

Approach 1: Naive Recursion (Exponential Time)

The most direct idea is to simulate every possible move sequence. From index i, a player can take 1, 2, or 3 stones and recursively evaluate the opponent’s best response. The score difference is computed as current_sum - opponent_best. This models the game as a zero‑sum decision tree. Without caching, the recursion repeatedly recomputes the same states, leading to O(3^n) time and O(n) recursion stack space. This approach demonstrates the game-theory formulation but becomes infeasible even for moderate input sizes.

Approach 2: Recursive Memoization (O(n) time, O(n) space)

The key observation is that the game state depends only on the starting index of the remaining stones. Cache the best score difference for each index using memoization. For position i, iterate over taking 1–3 stones, maintain a running sum, and compute sum - dfs(i + k). Store the maximum result in a memo table so repeated states are reused. This converts the exponential recursion into linear dynamic programming. Each index is solved once, and each state checks at most three options. Time complexity becomes O(n) and space complexity O(n) for the memo plus recursion stack. This approach clearly expresses the optimal-play logic and maps directly to problems in Game Theory and Dynamic Programming.

Approach 3: Dynamic Programming with Suffix Evaluation (O(n) time, O(n) space)

An iterative DP removes recursion overhead. Define dp[i] as the maximum score difference the current player can achieve starting from index i. Traverse the array from right to left. At each position, try taking 1–3 stones, track the running sum, and update dp[i] = max(sum - dp[i+k]). This works because dp[i+k] already represents the opponent’s optimal advantage from the next position. The recurrence captures the competitive nature of the game while avoiding repeated computation. The algorithm processes each index once with at most three transitions, giving O(n) time and O(n) space. Since the input is a simple Array, the DP array is the only extra structure required.

Recommended for interviews: Interviewers expect the dynamic programming formulation. Start by explaining the recursive game-state definition and score difference idea. That demonstrates understanding of optimal play. Then transition to memoization or bottom-up DP to reach the O(n) solution. The suffix DP version is typically preferred in production code because it avoids recursion depth issues and is easier to reason about.

Approach 1: Dynamic Programming with Suffix Evaluation

This approach involves using dynamic programming to evaluate possible outcomes from the end of the stone array to the beginning. This allows us to make optimal decisions at each step because we know the best scores for the rest of the game. The idea is to calculate the maximum score difference Alice can enforce using a suffix-based strategy.

The code initializes a DP array to store maximum scores achievable from each position. It iterates backward through the stone array, calculating for each position the maximum score difference possible by taking 1, 2, or 3 stones and subtracting the opponent's best response.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time Complexity: O(n), where n is the number of stones. Each stone position is computed once.
Space Complexity: O(n), where n is the number of stones. It uses an array of size n+1 to store computed values.

Try this approach in the editor →

Approach 2: Recursive Memoization

This approach leverages the recursive computation of outcomes with memoization. We recursively compute the score differences at each step, caching the results to avoid redundant calculations. At each stone index, the player's optimal score is determined by considering 1 to 3 stone choices.

The Python solution employs a memoization decorator to cache previously computed results, optimizing recursive calls. This avoids recalculating results for subproblems, ensuring efficiency. Each call makes decisions based on potential stone selections and returns the best achievable score differential for Alice.

Code

Python

Complexity

Time Complexity: O(n), due to computation of score differences for unique indices once per index.
Space Complexity: O(n), from the recursive call stack and memoization cache storing outcomes for each state.

Try this approach in the editor →

Approach 3: Memoization Search

We design a function dfs(i), which represents the maximum score difference that the current player can obtain when playing the game in the range [i, n). If dfs(0) > 0, it means that the first player Alice can win; if dfs(0) < 0, it means that the second player Bob can win; otherwise, it means that the two players tie.

The execution logic of the function dfs(i) is as follows:

  • If i geq n, it means that there are no stones to take now, so we can directly return 0;
  • Otherwise, we enumerate that the current player takes the first j+1 piles of stones, where j \in {0, 1, 2}. Then the score difference that the other player can get in the next round is dfs(i + j + 1), so the score difference that the current player can get is sum_{k=i}^{i+j} stoneValue[k] - dfs(i + j + 1). We want to maximize the score difference of the current player, so we can use the max function to get the maximum score difference, that is:

$ dfs(i) = max_{j \in {0, 1, 2}} \left{sum_{k=i}^{i+j} stoneValue[k] - dfs(i + j + 1)\right}

To prevent repeated calculations, we can use memoization search.

The time complexity is O(n), and the space complexity is O(n). Where n$ is the number of piles of stones.

Code

Python

Java

C++

Go

TypeScript

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Dynamic Programming with Suffix Evaluation

Time Complexity: O(n), where n is the number of stones. Each stone position is computed once.
Space Complexity: O(n), where n is the number of stones. It uses an array of size n+1 to store computed values.

Recursive Memoization

Time Complexity: O(n), due to computation of score differences for unique indices once per index.
Space Complexity: O(n), from the recursive call stack and memoization cache storing outcomes for each state.

Memoization Search

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Naive RecursionO(3^n)O(n)Conceptual understanding of the game tree and optimal-play reasoning
Recursive MemoizationO(n)O(n)Clear top-down implementation of the optimal strategy with caching
Dynamic Programming with Suffix EvaluationO(n)O(n)Interview-ready and production-friendly solution without recursion

Video Solution

Leetcode 1406. Stone Game IIIFraz17,402 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Stone Game III easy or hard?
Stone Game III is classified as Hard because it combines dynamic programming with optimal game strategy. The challenge lies in modeling the state as a score difference and recognizing the recurrence dp[i] = max(sum − dp[i+k]).
Stone Game III Python/Java solution
Python and Java solutions typically implement either top-down memoization or bottom-up dynamic programming. Both compute the maximum score difference for each index while considering the next three possible moves, achieving O(n) time complexity.
How to solve Stone Game III in O(n)?
Use dynamic programming where dp[i] represents the best score difference from index i. Traverse the array from right to left and compute dp[i] = max(sum_of_taken_stones − dp[i+k]) for k = 1 to 3. Each state is computed once, resulting in O(n) time.
What is the best approach for Stone Game III?
Dynamic programming with suffix evaluation is the most efficient approach. Define dp[i] as the maximum score difference a player can achieve starting at index i. By trying 1–3 stones and subtracting the opponent’s optimal result (dp[i+k]), the algorithm determines the best move in O(n) time.
Is Stone Game III asked at Google/Amazon/Meta?
Stone Game III belongs to the dynamic programming and game theory category commonly asked by companies like Google, Amazon, and Meta. Interviewers use it to test optimal decision modeling, state transitions, and DP optimization skills.
What data structure is used in Stone Game III?
The main structure is a dynamic programming array or memoization map indexed by the stone position. The input itself is a simple array, and the DP structure stores the best score difference achievable from each index.
What is the time complexity of Stone Game III?
The optimal solution runs in O(n) time because each index in the array is processed once and evaluates at most three transitions. Space complexity is O(n) for the DP array or memo table used to store intermediate results.

Ready to solve this problem?

Practice Stone Game III with our built-in code editor and test cases.

Practice on FleetCode