Moving Stones Until Consecutive II

LeetCode Q 1040 - Moving Stones Until Consecutive II

On an infinite number line, the position of the i-th stone is given by stones[i]. Call a stone an endpoint stone if it has the smallest or largest position.

Each turn, you pick up an endpoint stone and move it to an unoccupied position so that it is no longer an endpoint stone.

In particular, if the stones are at say, 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, ie. the stones are in consecutive positions.

When the game ends, what is the minimum and maximum number of moves that you could have made? Return the answer as an length 2 array: answer = [minimum_moves, maximum_moves]

Example 1: Input: [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: [6,5,4,3,10] ; Output: [2,3]
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.

Example 3: Input: [100,101,104,102,103] ; Output: [0,0]

Note:

  • 3 <= stones.length <= 10^4
  • 1 <= stones[i] <= 10^9
  • stones[i] have distinct values.

Solution

  1. How to find maximum steps?
  • find maximum interval. i.e. Math.max(A[n - 1] - A[1], A[n - 2] - A[0]).
  • Maximum steps equal to the empty slot within the maximum interval, i.e. maximum steps = maximum interval - (n - 3).
  1. How to find minimum steps?
    Transfer this question into a question like:
    Find the longest subsequence of a sorted array with max difference == n - 1.

For example, [1, 3, 4, 5, 8], we just need to move 1 and 8 close to 3, 4, 5, so we need n - len: 5 - 3 = 2 steps.
Special case: [1, 2, 3, 4, 8], we need 2 steps too. Therefore, if there are n - 1 consecutive numbers, add 1 to minimum steps.

Code:

public int[] numMovesStonesII(int[] A) {
	
	Arrays.sort(A);

	int len = A.length;
	int maxCon = 0, start, end, j = 0;
	int si = 0, ei = 0;

	for (int i = 0; i < A.length; i++) {
		start = A[i]; end = start + len;

		while (j < len && A[j] < end)
			j++;

		if (j - i > maxCon || (j - i == maxCon && A[j - 1] - A[i] > ei - si) {
			maxCon = j - i; si = A[i]; ei = A[j - 1];
		}
	}

	int minMoves = n - maxCon;

	if(maxCon == n-1 && ei-si == maxCon-1) minMoves++;
	
	if(maxCon == n) minMoves = 0;
	
	int largestInterval = Math.max(A[n-1] - A[1], A[n-2] - A[0]) - 1;
	int maxMoves =  largestInterval - (n - 3);
	
	return new int[]{minMoves, maxMoves};
}

   Reprint policy


《Moving Stones Until Consecutive II》 by Tong Shi is licensed under a Creative Commons Attribution 4.0 International License
 Previous
3Sum 3Sum
LeetCode Q 15 - 3SumGiven an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find
2019-06-05 Tong Shi
Next 
Height Checker Height Checker
LeetCode Q 1051 - Height CheckerStudents are asked to stand in non-decreasing order of heights for an annual photo. Retu
2019-06-05 Tong Shi
  TOC