头脑风暴之俩球之间的磁力

255 阅读3分钟

「这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

题目

在代号为 C-137 的地球上,Rick 发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子,第 i 个篮子的位置在 position[i] ,Morty 想把 m 个球放到这些篮子里,使得任意两球间 最小磁力 最大。

已知两个球如果分别位于 x 和 y ,那么它们之间的磁力为 |x - y| 。

给你一个整数数组 position 和一个整数 m ,请你返回最大化的最小磁力。

示例1:

输入:position = [1,2,3,4,7], m = 3
输出:3
解释:将 3 个球分别放入位于 147 的三个篮子,两球间的磁力分别为 [3, 3, 6]。最小磁力为 3 。我们没办法让最小磁力大于 3

示例2:

输入:position = [5,4,3,2,1,1000000000], m = 2
输出:999999999
解释:我们使用位于 11000000000 的篮子时最小磁力最大。

解题思路

  1. 两球的最小距离的最小值,是1;最小距离的最大值是 (最后位置的球坐标 - 最前位置的球坐标) / (球数-1),这里需要先对position数组排序,那么易得最小球间距离的最大值为 (position[position.length - 1] - position[0]) / (m-1)。

  2. 有最小和最大,直觉想到二分法。以二分的中间值,作为间距去摆放球。如果摆放的球数 >=m, 可认为需要增加球间距 (同时保存中间值作为候选答案); 否则需要减少球间距。

  3. 一点总结是,当碰到求最大或最小值的时候,是否可转化为二分法。属于直觉和经验吧。

代码实现

class Solution {
    public int maxDistance(int[] position, int m) {
        Arrays.sort(position);
        int left = 1, right = position[position.length - 1] - position[0], ans = -1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (check(mid, position, m)) {
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;
    }

    public boolean check(int x, int[] position, int m) {
        int pre = position[0], cnt = 1;
        for (int i = 1; i < position.length; i++) {
            if (position[i] - pre >= x) {
                pre = position[i];
                cnt += 1;
            }
        }
        return cnt >= m;
    }
}

最后

  • 时间复杂度:O(nlog(nS)),其中 n 为篮子的个数,S 为篮子位置的上限。

  • 空间复杂度:O(logn),即为排序需要的栈空间。

**往期文章:

请你喝杯 ☕️ 点赞 + 关注哦~

  1. 阅读完记得给我点个赞哦,有👍 有动力
  2. 关注公众号--- HelloWorld杰少,第一时间推送新姿势

最后,创作不易,如果对大家有所帮助,希望大家点赞支持,有什么问题也可以在评论区里讨论😄~**