There are some stones in different positions on the X-axis. You are given an integer array stones
, the positions of the stones.
Call a stone an endpoint stone if it has the smallest or largest position. In one move, you pick up an endpoint stone and move it to an unoccupied position so that it is no longer an endpoint stone.
stones = [1,2,5]
, you cannot move the endpoint stone at position 5
, since moving it to any position (such as 0
, or 3
) will still keep that stone as an endpoint stone.The game ends when you cannot make any more moves (i.e., the stones are in three consecutive positions).
Return an integer array answer
of length 2
where:
answer[0]
is the minimum number of moves you can play, andanswer[1]
is the maximum number of moves you can play.
Example 1:
Input: stones = [7,4,9] Output: [1,2] Explanation: We can move 4 -> 8 for one move to finish the game. Or, we can move 9 -> 5, 4 -> 6 for two moves to finish the game.
Example 2:
Input: stones = [6,5,4,3,10] Output: [2,3] Explanation: We can move 3 -> 8 then 10 -> 7 to finish the game. Or, we can move 3 -> 7, 4 -> 8, 5 -> 9 to finish the game. Notice we cannot move 10 -> 2 to finish the game, because that would be an illegal move.
Constraints:
3 <= stones.length <= 104
1 <= stones[i] <= 109
stones
are unique.This problem involves finding the minimum and maximum number of moves required to make a set of stones on the x-axis consecutive. A move consists of taking an endpoint stone (the stone with the smallest or largest position) and moving it to an unoccupied position such that it's no longer an endpoint stone. The game ends when the stones occupy three consecutive positions.
Understanding the Problem
The key is to realize that the minimum number of moves depends on finding the longest consecutive sequence within the sorted stones and filling the gaps. The maximum number of moves arises from strategically moving stones to maximize the number of moves needed before achieving consecutiveness.
Approach
Sort the Stones: Sort the input stones
array to easily identify consecutive sequences and endpoints.
Calculate Maximum Moves: The maximum number of moves occurs when the stones are spread out as much as possible. Consider the sorted stones. The maximum move is the larger of (max(stones) - min(stones) + 1) - (n-1)
and (stones[n-2] - stones[0] + 1) - (n-1)
. This essentially calculates the difference between the maximum possible length of the consecutive sequence and the actual length, and uses the second largest to determine the difference from the smallest stone. It subtracts (n-1)
because a consecutive sequence of n
stones needs n-1
intervals.
Calculate Minimum Moves: This is more complex. We use a two-pointer sliding window approach:
i
and j
are the pointers defining the window.j-i+1
) plus the gaps exceeds the total number of stones n
.n-1
and the difference between the largest and smallest stone in the window is n-2
, then it means only two moves are needed (minimum case).n - (j - i + 1)
, representing the number of stones to move to achieve consecutiveness given a consecutive subarray determined by the window.Time Complexity Analysis
Therefore, the overall time complexity is dominated by the sorting step, resulting in O(n log n).
Space Complexity Analysis
The space complexity is O(1) (constant) because we are using a small number of variables to store intermediate results, irrespective of the input size.
Code Implementation (Python)
def numMovesStonesII(stones):
stones.sort()
n = len(stones)
min_moves = n # Initialize with maximum possible moves
max_moves = max(stones[-1] - stones[1] + 1, stones[-2] - stones[0] + 1) - (n - 1)
i = 0
for j in range(n):
while stones[j] - stones[i] + 1 > n:
i += 1
if j - i + 1 == n - 1 and stones[j] - stones[i] == n - 2:
min_moves = min(min_moves, 2)
else:
min_moves = min(min_moves, n - (j - i + 1))
return [min_moves, max_moves]
The code in other languages (Java, C++, Go, TypeScript) follows a very similar structure and logic, with only syntactic differences to reflect the language's specific features. The core algorithm remains consistent across all implementations.