Skip to main content

Stone Game IV - Solution & Explanation

HardMathDynamic ProgrammingGame Theory13 min readAsked at: Microsoft
Practice this problem

Problem Statement

Alice and Bob take turns playing a game, with Alice starting first.

Initially, there are n stones in a pile. On each player's turn, that player makes a move consisting of removing any non-zero square number of stones in the pile.

Also, if a player cannot make a move, he/she loses the game.

Given a positive integer n, return true if and only if Alice wins the game otherwise return false, assuming both players play optimally.

 

Example 1:

Input: n = 1
Output: true
Explanation: Alice can remove 1 stone winning the game because Bob doesn't have any moves.

Example 2:

Input: n = 2
Output: false
Explanation: Alice can only remove 1 stone, after that Bob removes the last one winning the game (2 -> 1 -> 0).

Example 3:

Input: n = 4
Output: true
Explanation: n is already a perfect square, Alice can win with one move, removing 4 stones (4 -> 0).

 

Constraints:

  • 1 <= n <= 105

Approach Overview

Problem Overview: You are given n stones. Two players take turns removing a non‑zero square number of stones (1, 4, 9, 16, ...). The player who cannot make a move loses. Determine whether Alice, who plays first, can force a win if both players play optimally.

Approach 1: Recursive with Memoization (Time: O(n√n), Space: O(n))

This problem fits the classic win/lose state model used in game theory. From a state with n stones, try removing every square number i*i where i*i ≤ n. If any move leads the opponent to a losing state, the current state is winning. A plain recursive search recomputes the same states repeatedly, so store results in a memo table keyed by n. Each state explores at most √n moves and each state is computed once. This reduces the exponential search tree to O(n√n) time while using O(n) memory for memoization.

Approach 2: Dynamic Programming (Bottom-Up) (Time: O(n√n), Space: O(n))

The same win/lose logic can be implemented iteratively using dynamic programming. Define dp[i] as whether the current player wins with i stones remaining. Initialize dp[0] = false since no moves are possible. For each i from 1 to n, iterate over all perfect squares j*j ≤ i. If dp[i - j*j] is false, removing j*j stones forces the opponent into a losing position, so mark dp[i] = true. Each state checks up to √i transitions, leading to overall complexity O(n√n) with O(n) space.

The key insight: a position is winning if at least one move leads to a losing position for the opponent. This pattern appears frequently in impartial combinatorial games and many math and DP problems.

Recommended for interviews: The bottom‑up dynamic programming solution is what most interviewers expect. It demonstrates that you can model the game as a state transition problem and reason about winning vs losing states. Starting with the recursive formulation helps show your thinking, but converting it into iterative DP proves you understand optimization and avoids recursion overhead.

Approach 1: Dynamic Programming Approach

This approach uses Dynamic Programming to determine if Alice can win given n stones. We can maintain a boolean array dp where dp[i] represents whether Alice can win with i stones. A state is winning if there's any move that leaves the opponent in a losing state.

The array dp is initialized with false values. We iterate through each number up to n, checking all possible square numbers we can subtract. If there exists a square number such that the remaining stones leave Bob in a losing position, Alice is in a winning position.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time Complexity: O(n*sqrt(n)), Space Complexity: O(n)

Try this approach in the editor →

Approach 2: Recursive with Memoization

This approach involves a recursive solution with memoization to cache previously computed results. If n is already solved, we return the cached result. Otherwise, we recursively check if any move leaves the opponent in a losing position.

We use a helper function to recursively determine if a current state is winning while memoizing results for efficiency. The memo array is initialized with -1. For each recursive call, the function checks if removing any square results in a losing state for the opponent.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time Complexity: O(n*sqrt(n)), Space Complexity: O(n)

Try this approach in the editor →

Approach 3: Default Approach

Code

Python

Java

C++

Go

TypeScript

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Dynamic Programming Approach

Time Complexity: O(n*sqrt(n)), Space Complexity: O(n)

Recursive with Memoization

Time Complexity: O(n*sqrt(n)), Space Complexity: O(n)

Default Approach

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Naive RecursionExponentialO(n)Conceptual starting point to understand win/lose states in the game tree
Recursive with MemoizationO(n√n)O(n)Top‑down reasoning when you want a clear recursive definition of the game state
Dynamic Programming (Bottom-Up)O(n√n)O(n)Preferred interview solution; efficient iterative computation of all states

Video Solution

Leetcode 1510. Stone Game IVFraz7,700 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Stone Game IV easy or hard?
Stone Game IV is classified as Hard on LeetCode even though the implementation is short. The difficulty comes from recognizing the game theory pattern and modeling the problem as DP with winning and losing states.
Stone Game IV Python/Java solution
Both Python and Java implementations typically use a DP array of size n+1. For each index i, iterate through j*j ≤ i and mark dp[i] true if dp[i - j*j] is false. The same logic works across languages including C++, JavaScript, and C#.
How to solve Stone Game IV in O(n)?
A strict O(n) solution is not commonly used for this problem because each state must consider multiple square moves. The standard optimal approach checks all perfect squares ≤ n for every state, resulting in O(n√n) time using dynamic programming.
What is the best approach for Stone Game IV?
Dynamic Programming is the most reliable approach. Define dp[i] as whether the current player wins with i stones. For each i, try removing every square number j*j ≤ i and check if dp[i - j*j] is false. If such a move exists, dp[i] becomes true. This runs in O(n√n) time with O(n) space.
Is Stone Game IV asked at Google/Amazon/Meta?
Stone Game style problems frequently appear in interviews at companies like Google, Amazon, and Meta because they test reasoning about game states, recursion, and dynamic programming. Variants of this problem are commonly used to evaluate understanding of optimal play strategies.
What data structure is used in Stone Game IV?
The core data structure is a boolean DP array or memoization map that stores whether a state with i stones is winning or losing. The algorithm iterates through perfect squares and performs constant-time lookups in this table.
What is the time complexity of Stone Game IV?
The optimal solution runs in O(n√n) time. For each state from 1 to n, the algorithm iterates through all square numbers up to √n. The space complexity is O(n) for storing the DP or memoization table.

Ready to solve this problem?

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

Practice on FleetCode