【1040. Move stones until continuous II】

Source: LeetCode

describe:

On a number line of length infinite , the position of the ifirst pebble is stones[i]. If a pebble has the min/max position, then the pebble is called an endpoint pebble .

Each turn, you can pick up and move a terminal stone to an unoccupied position, making the stone no longer a terminal stone.

It's worth noting that if the stone is like stones = [1,2,5]this , you wo n't be able to move the endpoint stone at position 5, because no matter what position you move it to (such as 0 or 3), the stone will still be the endpoint stone.

When you cannot make any moves, that is, when the positions of these stones are continuous, the game is over.

What is the minimum and maximum number of moves you can make to make the game over? Returns the answer as an array of length 2answer = [minimum_moves, maximum_moves] : .

Example 1:

输入:[7,4,9]
输出:[1,2]
解释:
我们可以移动一次,4 -> 8,游戏结束。
或者,我们可以移动两次 9 -> 54 -> 6,游戏结束。

Example 2:

输入:[6,5,4,3,10]
输出:[2,3]
解释:
我们可以移动 3 -> 8,接着是 10 -> 7,游戏结束。
或者,我们可以移动 3 -> 7, 4 -> 8, 5 -> 9,游戏结束。
注意,我们无法进行 10 -> 2 这样的移动来结束游戏,因为这是不合要求的移动。

Example 3:

输入:[100,101,104,102,103]
输出:[0,0]

hint:

  • 3 <= stones.length <= 104
  • 1 <= stones[i] <= 109
  • The values ​​of stones[i] vary.

Method: double pointer

Ideas and Algorithms

Now the question is given a number axis of infinite length and an array stones of length n, indicating the different positions of n stones on the number axis, where the position of the 0th ≤ i < n stones is on stones[i], among them, if a stone The minimum/maximum position of the stone is called an endpoint stone. Now we need to move an endpoint stone to an unoccupied position every time, so that it is no longer an endpoint stone, and stop if the operation cannot be performed. We need to return the minimum and maximum number of operations that can be performed from the initial condition.

We remember that the length of these stones is the distance difference between the stones at the two ends, then we can get that the length of the stones is strictly decreasing each time the stone is moved, and since the total number of stones remains the same, the spaces between the stones are getting less and less . By moving, all the stones are finally made continuous, which is essentially to make the space between the stones 0. Now we start to think about how to solve the maximum and minimum operands. For the convenience of description, we might as well sort the stones in the array stones in ascending order of position and size, that is, satisfy

stones[0] < stones[1] < ⋯ < stones[n − 1]

First of all, if all stones are continuous at the beginning, that is, the vacant number stones[n − 1] − stones[0] + 1 − n is 0, then the operation cannot be performed at this time, and the maximum and minimum operands are both 0, otherwise:

  • Maximum number of operations: For the first time, we can only choose stones[0] or stones[n − 1] to move. Because it cannot continue to be an endpoint stone after moving, if you move stones[0], the space between stones[1] and stones[0] will be discarded; if you move stones[n − 1], then stones[n − 1] to stones[n − 2] will be discarded. If we move the endpoint stones to the nearest vacancy each time we move, after the first move, if we move stones[0], then this At this time, the two leftmost stones must be adjacent to each other. At this time, we will move the leftmost stone to the nearest space in subsequent operations until the operation cannot be performed, so that the remaining spaces will not be discarded. . If you move stones[n − 1], the two rightmost stones must be adjacent to each other at this time. At this time, we will move the rightmost stone to the nearest vacancy in subsequent operations until it is impossible to proceed. operation, so that the remaining vacancies are also not discarded. Since there must be one less space for each operation, after the first move, the above two operations are optimal operations, and because the initial total space is fixed, if we choose to move stones[0 for the first time ], the total number of operations that can be performed is
stones[n − 1] − stones[1] + 1 − (n − 1)        (1)
  If we choose to move stones[n− 1] for the first time, the total number of operations that can be performed is
stones[n − 2] − stones[0] + 1 − (n − 1)        (2)
  The larger of the two is then the largest operand.
  • Minimum number of operations: Finally, all stones are consecutively equivalent to all stones eventually moving into a window of length n.
    1. If there are consecutive n − 1 stones in the window, and if the gap between the remaining stone and the nearest stone in the window is 1, then only one operation is needed to make n stones continuous, otherwise we need to perform Two steps. For example, if there is a sequence of stone positions 1, 2, 3, 4, 6, then 1, 2, 3, 4 are continuous at this time, and the space between 6 and its nearest 4 is 1, we only need to move the stone with position 1 to the position The position of 5 is sufficient. Otherwise, if the sequence of stone positions is 1, 2, 3, 4, x, where x > 6, then we can move the stone at position 1 to position 6, and then move the stone at position x to position 5 . When the remaining stone is on the left side of the continuous sequence, the same conclusion can be obtained by analysis.
    2. Otherwise, we just choose the window that contains the most stones. We might as well set k stones, then n − k operations are needed to fill the gaps in the window. The proof is as follows.
      We might as well assume that there are stones at the left end of the window at this time (if not, you can move the window to the right until there are stones at the left end of the window, because the number of stones in the window will only increase a lot during the process of moving to the right, and will not change The nature of the most stones in the window), if there are stones at the right end of the window at this time, the remaining n − k stones can be moved to the empty spaces in the window in turn, otherwise the number of stones in the window is less than n − 1 at this time, because If the number of stones is equal to n − 1 and there is no stone at the right end of the window, then it is case 1. Then there are at least two stones outside. If there are two or more stones on the right side of the window, the rightmost stone can be moved to the right end of the window. Otherwise, if there is a stone on the right side of the window, there must be at least one stone on the left side of the window. The most left stone is moved to the right end of the window, at this time, the remaining n − k − 1 stones can be moved to the remaining vacancies in the window in turn. At this point the total number of moves is still n − k. If there are no stones on the right side of the window, we will move the window to the left so that there are stones at the right end of the window. At this time, the total number of moves required can be obtained as n − k through the above analysis process.

code:

class Solution {
    
    
public:
    vector<int> numMovesStonesII(vector<int>& stones) {
    
    
        int n = stones.size();
        sort(stones.begin(), stones.end());
        if (stones.back() - stones[0] + 1 == n) {
    
    
            return {
    
    0, 0};
        }
        int ma = max(stones[n - 2] - stones[0] + 1, stones[n - 1] - stones[1] + 1) - (n - 1);
        int mi = n;
        for (int i = 0, j = 0; i < n && j + 1 < n; ++i) {
    
    
            while (j + 1 < n && stones[j + 1] - stones[i] + 1 <= n) {
    
    
                ++j;
            }
            if (j - i + 1 == n - 1 && stones[j] - stones[i] + 1 == n - 1) {
    
    
                mi = min(mi, 2);
            } else {
    
    
                mi = min(mi, n - (j - i + 1));
            }
        }
        return {
    
    mi, ma};
    }
};

Execution Time: 16 ms, beats 93.75% of all C++ submissions by users
Memory Consumption: 12.7 MB, beats 96.25% of all C++ submissions
Complexity Analysis
Time Complexity: O(nlogn), where n is an array The length of the stones. Mainly for the time complexity of sorting.
Space complexity: O(logn), where n is the length of the array stones. Mainly for the space overhead of sorting.
author: LeetCode-Solution

Guess you like

Origin blog.csdn.net/Sugar_wolf/article/details/130004901