力扣3281. 范围内整数的最大得分

这一题的大意是给出整数数组,和一个整数d,现在告诉我们每一个数组中的元素代表一个区间的左端点,d是区间的长度,那么每一个元素就可以表示一个区间:
[start[i],start[i]+d],现在让我们找得分,什么算是得分呢?就是相邻区间的差的绝对值,我们希望在每一个区间内都找一个点,从而可以计算得相邻点的差的绝对值。而
得分就是这些差的绝对值的最小值。
现在让我们找最大的得分。
最大化最小值,很明显是二分答案。
关键在于check函数的书写,如何判断在假设最大得分为x的时候,数组和d能否找到符合条件的区间的点。
这里要贪心地想,我们首先要把起点尽可能的小,然后看起点+x能否落在相邻的区间上,如果能落上就继续以落上的点作为起点,以此类推,直到所有的点都满足这个条件。
那么如果起点+x过小呢,它是无法落在相邻起点的,也就是差值过小,不是我们要找的最大差值,我们还是把它当作是正确的,然后用相邻区间的左端点作为起点,继续判断起点+x能否落在相邻的区间上,直至所有的点符合条件。对于差值过小,我们并不认为它是错的返回false,而是返回true,因为会继续二分,逼近最大值。因此只有差值过大的情况才返回true。
完整代码如下:
class Solution {
public:bool check(int x,vector<int>& start,int d){//必须保证每一个相邻两个的差至少为x//如果不满足,说明得分不是最大的//我们只需要贪心的看相邻两个区间,存不存在两个点的距离是不是// 0 3 6long long pre=start[0];for(int i=0;i<start.size()-1;i++){if((pre+x<=(long long)start[i+1]+d)){//说明符合pre=max((long long)start[i+1],(long long)pre+x);}else{return false;}}return true;}int maxPossibleScore(vector<int>& start, int d) {// 6 8// 0 2// 3 5int l=0;int r=2*1e9;int ans=0;sort(start.begin(),start.end());while(l<=r){int mid=l+(r-l)/2;if(check(mid,start,d)){ans=max(ans,mid);l=mid+1;}else{r=mid-1;}}return ans;}
};
时间复杂度O(nlogn)
