题目连接算法
二分+贪心sql
时间复杂度O(nlogn + nlogm)
数组
1.根据题意描述,咱们须要将m个球放入到n个篮子中,根据题目中数据范围描述发现m <= n,故能够将一个球放入到一个篮子中。这道题主要就是要求出相邻的两个球之间的距离的最小值,并且要尽量的让这个最小值最大化code
2.分析完了题意,下面来分析一下如何解题。刚开始的思路是首先排序,而后将第一个球放到数组的第一个位置,而后根据剩余的球的个数枚举球的位置。但由于还须要记录相邻两个球的距离差,若是这样纯暴力的话写起来太过于繁琐,而且耗时大,最终该思路未果。在搜索了大佬们的解题思路后,了解到可使用二分思想来对磁力进行二分,具体思路以下。blog
3.对于一些球,它们之间磁力的最大值是poisiton数组中元素的最大值减去最小值(这里先不考虑球的个数),那么咱们就能够肯定了磁力的区间范围[l,r]
,而后将[l,r]
划分为[l,mid-1]
、[mid,r]
,为何要这样划分呢,由于题目中说了要最大化最小磁力,因此咱们要尽量的使得mid更大。划分条件就是判断position数组是否可以找到m个篮子使得它可以知足相邻的两个球之间的距离大于等于mid,若是知足,则l=mid
,不然r=mid-1
。排序
4.为了使得最小磁力最大化,咱们可使其中一个球位于最左边的那个篮子里,而后再以此枚举球的位置,使得相邻的两个球的距离大于等于mid。leetcode
5.由此,这道题的整体思路是:先排序,而后二分。get
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大佬的二分查找算法模板it