专栏首页用户6093955的专栏leetcode1552题解【二分+贪心】

leetcode1552题解【二分+贪心】

leetcode1552.两球之间的磁力

题目链接

算法

二分+贪心

时间复杂度O(nlogn + nlogm)

1.根据题意描述,我们需要将m个球放入到n个篮子中,根据题目中数据范围描述发现m <= n,故可以将一个球放入到一个篮子中。这道题主要就是要求出相邻的两个球之间的距离的最小值,而且要尽可能的让这个最小值最大化

2.分析完了题意,下面来分析一下如何解题。刚开始的思路是首先排序,然后将第一个球放到数组的第一个位置,然后根据剩余的球的个数枚举球的位置。但因为还需要记录相邻两个球的距离差,如果这样纯暴力的话写起来太过于繁琐,并且耗时大,最终该思路未果。在搜索了大佬们的解题思路后,了解到可以使用二分思想来对磁力进行二分,具体思路如下。

3.对于一些球,它们之间磁力的最大值是poisiton数组中元素的最大值减去最小值(这里先不考虑球的个数),那么我们就可以确定了磁力的区间范围[l,r],然后将[l,r]划分为[l,mid-1][mid,r],为什么要这样划分呢,因为题目中说了要最大化最小磁力,所以我们要尽可能的使得mid更大。划分条件就是判断position数组是否能够找到m个篮子使得它能够满足相邻的两个球之间的距离大于等于mid,如果满足,则l=mid,否则r=mid-1

4.为了使得最小磁力最大化,我们可以使其中一个球位于最左边的那个篮子里,然后再以此枚举球的位置,使得相邻的两个球的距离大于等于mid。

5.由此,这道题的总体思路是:先排序,然后二分。

C++代码

class Solution {
public:
    int maxDistance(vector<int>& position, int m) {
        sort(position.begin(), position.end());
        int len = position.size();
        int l = 1, r = position[len - 1] - position[0];
        while(l < r){
            int mid = l + r + 1>> 1;
            if(check(mid, position, m))
                l = mid;
            else
                r = mid - 1;
        }
        return l;
    }
    bool check(int k, vector<int>& position, int m){
        int len = position.size();
        int last = position[0];         //last用于记录上一个存放球的篮子的位置
        int t = 1;             //记录已经放入到篮子的球的个数
        for(int i = 1; i < len; i++){
            if(position[i] - last >= k){
                ++t;
                last = position[i];
                if(t == m) return true;
            }
        }
        return false;
    }
};

这道题使用的二分模板来源于yxc大佬的二分查找算法模板

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 蓝桥杯突击复习准备——部分算法汇总

    当然,上面这个状态转移方程不适用于a数组长度较大的情况。比如AcWing896. 最长上升子序列 II (AC代码,思路在代码中)

    _DIY
  • 【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)模版】

    注意此模板只适用于查找a中是否存在v,存在的话则返回其中一个符合条件的位置,并不一定只有那一个位置,这个视情况而定。

    _DIY
  • 【Pet HDU - 4707 】【利用并查集找深度】

    _DIY
  • LeetCode 1099. 小于 K 的两数之和(二分查找)

    给你一个整数数组 A 和一个整数 K,请在该数组中找出两个元素,使它们的和小于 K 但尽可能地接近 K,返回这两个元素的和。

    Michael阿明
  • Find the nth digit(二分查找) - HDU 1597

    ...

    ACM算法日常
  • bzoj 2120 数颜色 带修莫队

    用户2965768
  • c++指针函数的使用——回调函数

    拾点阳光
  • 团体程序设计天梯赛-练习集 L1-013 计算阶乘和

    C you again 的博客
  • java – 为什么InputStream#read()返回一个int而不是一个字节?

    首先字节正好是8位,所以使用8位的char类型数据来与字节数据相互一一对应是最好的选择?但是为何方法InputStream#read()需要返回int类型值呢?

    Fisherman渔夫
  • [随缘一题]雷达监测

    一个2D平面上有一堆雷达(雷达有x, y坐标,以及能探测到的范围r半径)。现在有一辆小车要从y = 0和y = 1的区间里面通过并且不能被雷达探测到。若被检测到...

    呼延十

扫码关注云+社区

领取腾讯云代金券