LeetCode 1040. Moving Stones Until Consecutive II(java)

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.

思路:求min: 找到一個<=n的間隔內連續數字個數最多的,然後min = n-個數。如果min = 1, 判斷是否爲1,2,3,10的情況,如果是,則min+1. 求max: 比較兩個端點和最近點的距離,max = 所有點之間的距離 - 小的端點距離 + 1(移動一個端點到另一端) - 1(移動完另一端距離-1);
class Solution {
    public int[] numMovesStonesII(int[] stones) {
        int[] res = new int[2];
        Arrays.sort(stones);
        int n = stones.length;
        //min
        int min = 0;
        for (int i = 0; i < n; i++) {
            int compute = 1;
            int j = i + 1;
            while(j < n && stones[j] - stones[i] <= n - 1) {
                compute++;
                j++;
            }
            min = Math.max(min, compute);
        }
        //max
        int max = 0;
        for (int i = 1; i < n; i++) {
            max = max + stones[i] - stones[i-1] - 1;
        }
        if (stones[1] - stones[0] <= stones[n-1] - stones[n-2])  max = max - (stones[1] - stones[0] - 1);
        else max = max - (stones[n-1] - stones[n-2] - 1);
        res[0] = n - min;
        if (res[0] == 1) {
            if ((stones[n-2] - stones[0] == n-2 && stones[n-1] != stones[n-2] + 2) 
                || (stones[n-1] - stones[1] == n-2 && stones[0] + 2 != stones[1])) {
                res[0] = res[0] + 1;
            }
        }
        res[1] = max;
        return res;
    }
}
思路二:
class Solution {
    public int[] numMovesStonesII(int[] stones) {
        int[] res = new int[2];
        Arrays.sort(stones);
        int n = stones.length;
        //min
        int min = n-1;
        int i = 0;
        for (int j = 0; j < n; ++j) {
            while (stones[j] - stones[i] >= n) ++i;
            //j-i+1 == n-1表示從i到j有n個可能的連續數裏的n-1個。第二個判斷條件判斷n-1個數都連續,還是有一個地方不連續,差1。
            //j-i+1 == n表示n個數都連續。
            if (j - i + 1 == n - 1 && stones[j] - stones[i] +1 == n-1) {
                //n-1個數都連續
                min = Math.min(min, 2);
            } else {
                min = Math.min(min, n - (j - i + 1));
            }
        }
        res[0] = min;
        //max
        int max = 0;
        max = Math.max(stones[n-1] - stones[1] - (n-2), stones[n-2] - stones[0] - (n-2));
        res[1] = max;
        return res;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章