LeetCode - 1552 Magnetic force between two balls

Table of contents

Topic source

topic description

example

hint

topic analysis

Algorithm source code


Topic source

1552. Magnetic force between two balls - LeetCode

topic description

On Earth, code-named C-137, Rick discovers that if he places two balls in his newly invented basket, a special form of magnetic force develops between them. Rick has n empty baskets, the position of the i-th basket is at position[i], and Morty wants to put m balls into these baskets so that the minimum magnetic force between any two balls is the largest.

It is known that if two balls are located at x and y respectively, then the magnetic force between them is |x - y|.

Given an integer array position and an integer m , please return the minimum magnetic force that maximizes.

example

enter position = [1,2,3,4,7], m = 3
output 3
illustrate Put 3 balls into the three baskets located at 1, 4 and 7 respectively, and the magnetic forces between the two balls are [3, 3, 6] respectively. The minimum magnetic force is 3. We can't make the minimum magnetic force greater than 3.
enter position = [5,4,3,2,1,1000000000], m = 2
output 999999999
illustrate We use baskets at 1 and 1000000000 where the minimum magnetic force is maximum.

hint

  • n == position.length
  • 2 <= n <= 10^5
  • 1 <= position[i] <= 10^9
  • All integers in position are distinct from each other.
  • 2 <= m <= position.length

topic analysis

This question is a minimization maximization problem, which can be solved using the dichotomy method.

The title description says

It is known that if two balls are located at x and y respectively, then the magnetic force between them is |x - y|.

Then it can be concluded that magnetic force = distance, that is, the greater the distance, the greater the magnetic force.

This question needs to put m balls into n baskets. If you follow the combination strategy, you will get a placement method. There is a magnetic force between two adjacent balls in each placement method. Assume:

  • The minimum value of the magnetic force between two adjacent balls in placement mode 1 is a
  • The minimum value of the magnetic force between two adjacent balls in placement mode 2 is b
  • ...
  • The minimum value of the magnetic force between two adjacent balls placed in X is x

Then the solution to this question is max(a, b, ..., x). That is to find the maximum minimum magnetic force.

If this question uses the combination strategy to solve the maximum and minimum magnetic force, it will time out. The best strategy is to use two points.

 

Since the title has given the positions of n baskets, we sort the positions in ascending order, then we can get:

  • The maximum magnetic force between the two balls = position[n-1] - position[0]

And the magnetic force between the two balls is at least 1.

In this question, the magnetic force is the distance, so we have the minimum value of the distance between the two balls min: 1, and the maximum value max: position[n-1] - position[0]

Next, you can use the binary strategy to find an intermediate value mid = (min + max) / 2, and then use the mid value as the minimum distance dis between two balls. The distance between them is greater than or equal to dis, then dis is a possible solution to this problem.

The specific logic for checking whether it is satisfied is as follows:

First of all, we can definitely put down the first ball, and the best place to place the first ball is position[0].

We record:

  • The latest ball position curPos = position[0]
  • The number of placed balls count = 1

Next, we traverse from i = 1 to i = n - 1:

  • If position[i] - curPos >= dis, it means that the next ball is placed at position[i], which can meet the condition of the minimum distance dis, at this time count++, and update curPos = position[i]
  • If position[i] - curPos < dis, it means that the next ball cannot be placed at position[i], at this time we can only i ++ 

At the end of the traversal:

  • If count >= m, it means that m balls can be put into n baskets under the condition of satisfying the minimum distance dis between two pairs. At this time, dis is a possible solution, but not necessarily the optimal solution. We record this After the dis at the time, try to increase the left boundary of the dichotomous range, that is, after min = mid + 1, continue to calculate the middle value mid
  • If count < m, it means that m balls cannot be placed in n baskets while satisfying the minimum distance between two pairs of dis, which means that the current dis is too large, and we should reduce dis, that is, reduce the right boundary of the two-point range, that is max = mid - 1, continue to find the middle mid

Java algorithm source code

class Solution {
    public int maxDistance(int[] position, int m) {
        Arrays.sort(position);

        int minDis = 0;
        int maxDis = position[position.length-1] - position[0];
        int ans = 0;

        while(minDis <= maxDis) {
            int mid = (minDis + maxDis) >> 1;
            if(check(position, m, mid)) {
                ans = mid;
                minDis = mid + 1;
            } else {
                maxDis = mid - 1;
            }
        }

        return ans;
    }

    public boolean check(int[] position, int m, int dis) {
        int count = 1;
        int curPos = position[0];

        for(int i=1; i<position.length; i++) {
            if(position[i] - curPos >= dis) {
                count++;
                curPos = position[i];
            }
        }

        return count >= m;
    }
}

JavaScript algorithm source code

/**
 * @param {number[]} position
 * @param {number} m
 * @return {number}
 */
var maxDistance = function(position, m) {
    position.sort((a,b)=>a-b)

    let minDis = 1
    let maxDis = position.at(-1) - position[0]
    let ans = 0

    while(minDis <= maxDis) {
        const mid = (minDis + maxDis) >> 1

        if(check(position, m, mid)) {
            ans = mid
            minDis = mid + 1
        } else {
            maxDis = mid - 1
        }
    }

    return ans
};

function check(position, m, dis) {
    let count = 1
    let curPos = position[0]

    for(let i=1; i<position.length; i++) {
        if(position[i] - curPos >= dis) {
            count++;
            curPos = position[i]
        }
    }

    return count >= m
}

Python algorithm source code

class Solution(object):
    def maxDistance(self, position, m):
        """
        :type position: List[int]
        :type m: int
        :rtype: int
        """
        position.sort()

        minDis = 1
        maxDis = position[-1] - position[0]
        ans = 0

        while minDis <= maxDis:
            mid = (minDis + maxDis) >> 1
            if(self.check(position, m, mid)):
                ans = mid
                minDis = mid + 1
            else:
                maxDis = mid - 1
        
        return ans
    
    def check(self, position, m, dis):
        count = 1
        curPos = position[0]

        for i in range(1, len(position)):
            if position[i] - curPos >= dis:
                count += 1
                curPos = position[i]
        
        return count >= m

Guess you like

Origin blog.csdn.net/qfc_128220/article/details/130633897