LeetCode - 1552 两球之间的磁力

这篇具有很好参考价值的文章主要介绍了LeetCode - 1552 两球之间的磁力。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

题目来源

题目描述

示例

提示

题目解析

算法源码


题目来源

1552. 两球之间的磁力 - 力扣(LeetCode)

题目描述

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

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

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

示例

输入 position = [1,2,3,4,7], m = 3
输出 3
说明 将 3 个球分别放入位于 1,4 和 7 的三个篮子,两球间的磁力分别为 [3, 3, 6]。最小磁力为 3 。我们没办法让最小磁力大于 3 。
输入 position = [5,4,3,2,1,1000000000], m = 2
输出 999999999
说明 我们使用位于 1 和 1000000000 的篮子时最小磁力最大。

提示

  • n == position.length
  • 2 <= n <= 10^5
  • 1 <= position[i] <= 10^9
  • 所有 position 中的整数 互不相同 。
  • 2 <= m <= position.length

题目解析

本题是最小值最大化问题,可以使用二分法求解。

本题描述中说

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

则可以得出,磁力 = 距离,即距离越大,磁力越大。

本题需要将m个球放到n个篮子中,如果按照求组合的策略,则会得出LeetCode - 1552 两球之间的磁力,算法与数据结构,leetcode,算法,二分种放置方式,每种放置方式的两两相邻球之间都有一个磁力,假设:

  • 放置方式1的两两相邻球之间的磁力的最小值为a
  • 放置方式2的两两相邻球之间的磁力的最小值为b
  • ...
  • 放置方式X的两两相邻球之间的磁力的最小值为x

那么本题的题解就是 max(a, b, ..., x)。即求最大的最小磁力。

本题如果用求组合的策略来求解最大的最小磁力的话,则会超时。最佳策略是用二分。

 

由于题目已经给定了n个篮子的位置position,我们将position进行升序,则可得出:

  • 两球之间的磁力最大值 = position[n-1] - postion[0]

而两球之间的磁力至少为1。

本题中磁力就是距离,因此我们就有了两球之间距离的最小值min:1,和最大值max:position[n-1] - postion[0]

接下来就可以用二分策略,求得一个中间值mid = (min + max) / 2,然后将mid值作为两球之间的最小间距dis,如果有放置策略可以满足所有两两相邻球之间的距离都大于等于dis,则dis就是本题的一个可能解。

具体检查是否满足的逻辑如下:

首先,我们肯定可以放下第一个球,且第一个球的最佳放置位置就是position[0]。

我们记录:

  • 最新放球位置 curPos = position[0]
  • 已放置球个数 count = 1

接下来,我们从 i = 1 开始遍历,到 i = n - 1结束:

  • 如果position[i] - curPos >= dis,则说明将下一个球放到position[i]位置,可以满足最小间距dis的条件,此时count++,且更新curPos = position[i]
  • 如果position[i] - curPos < dis,则说明下一个球不能放到position[i]位置,此时我们只能 i ++ 

遍历结束时:文章来源地址https://www.toymoban.com/news/detail-632023.html

  • 如果count >= m,则说明m个球都能够在满足两两之间最小间距dis的情况下放到n个篮子中,此时dis就是一个可能解,但不一定时最优解,我们记录此时的dis后,尝试增大二分范围左边界,即min = mid + 1后,继续求中间值mid
  • 如果count < m,则说明m个球不能在满足两两之间最小间距dis的情况下放到n个篮子中,则说明当前dis大了,我们应该缩小dis,即减少二分范围的右边界,即max = mid - 1,继续求中间mid

Java算法源码

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算法源码

/**
 * @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算法源码

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

到了这里,关于LeetCode - 1552 两球之间的磁力的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法与数据结构】494、LeetCode目标和

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题和这道题【算法与数据结构】1049、LeetCode 最后一块石头的重量 II类似,同样可以转换成01背包问题。下面开始论述。假设添加正号的整数子集和为 p o s i t i v e positive p os i t

    2024年01月20日
    浏览(45)
  • 【算法与数据结构】474、LeetCode一和零

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题要找strs数组的最大子集,这个子集最多含有 m m m 个0和 n n n 个1。本题也可以抽象成一个01背包的问题。其中,strs内的元素就是物品,而 m m m 和 n n n 就是背包的维度。 d p [

    2024年01月22日
    浏览(42)
  • 【算法与数据结构】377、LeetCode组合总和 Ⅳ

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题明面上说是组合,实际上指的是排列。动态规划排列组合背包问题需要考虑遍历顺序。 d p [ i ] dp[i] d p [ i ] 指的是nums数组中总和为target的元素排列的个数。 d p [ i ] dp[i] d p [

    2024年01月23日
    浏览(42)
  • 【python与数据结构】(leetcode算法预备知识)

    笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ 1.数字类型: 整数(int):表示整数值,例如 1、-5、100。 浮点数(float):表示带有小数部分的数字,例如 3.14、-0.5、2.0。 复数(complex):表示实部和虚部的复数,例如 2+3j。 2.布尔类型(bool): 表示真(True)或假(

    2024年02月08日
    浏览(39)
  • 【算法与数据结构】232、LeetCode用栈实现队列

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :这道题要求我们用栈模拟队列(工作上一定没人这么搞)。程序当中,push函数很好解决,直接将元素push进输入栈当中。pop函数需要实现队列先进先出的操作,而栈是先进后出。只

    2024年02月12日
    浏览(44)
  • 【算法与数据结构】654、LeetCode最大二叉树

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树这两道题有些类似,相关代码可以互相参考,本题明示了要用递归来做,那么递归三要素不可缺少: 输入参数和返

    2024年02月09日
    浏览(46)
  • 【算法与数据结构】63、LeetCode不同路径 II

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :参考【算法与数据结构】62、LeetCode不同路径的题目,可以发现本题仅仅是多了障碍物。我们还是用动态规划来做。有障碍物的地方无法到达,因此路径数量为0,只需要将障碍物位

    2024年02月02日
    浏览(57)
  • 【算法与数据结构】226、LeetCode翻转二叉树

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :这道题的思路很简单,本质上就是遍历每一个节点,然后交换左右节点。我们可以用前中后遍历或者是层次遍历法来做,参考这两篇文章,【算法与数据结构】144、94、145LeetCode二

    2024年02月16日
    浏览(41)
  • 【算法与数据结构】28、LeetCode实现strStr函数

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :首先判断字符串是否合法,然后利用for循环,取出子字符串利用compare函数进行比较。    程序如下 : 复杂度分析: 时间复杂度: O ( n ∗ m ) O(n * m) O ( n ∗ m ) ,假设haystack的长

    2024年02月12日
    浏览(45)
  • 【算法与数据结构】518、LeetCode零钱兑换 II

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题的硬币是无数的,因此本题可以抽象成一个完全背包问题。完全背包和01背包的不同之处在于完全背包式从前往后遍历的。在本题的完全背包问题中,amount代表背包的最大重量

    2024年01月23日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包