題目連接算法
二分+貪心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