题目描述
给定一个数组ar,代表每个人的能力值。再给定一个非负数k
如果两个人能力差值正好为k, 那么可以凑在一起比赛
一局比赛只有两个人
返回最多可以同时有多少场比赛
比如: [3,1,5,7],最多同时有2场比赛[3,1];[5,7]
题目解析
贪心 + 滑动窗口
先将数组排序,用窗口。
举个例子:
(1)刚开始,L和R均在1位置
(2)L和R能不能比赛?不能,因为它们是一个人,那么R后移
- 必须要区分是不是同一个人,因为k有可能为0
(3)L和R能不能比赛?看两者差值 = A[R] - A[L]
- 差值 < K,就让R动(差值要变大)
- 差值 = K,能比赛
- 差值 > K,就让L动(差值要变小)
这里差值 = 0,不能比赛,R移动一位
(3)L和R能不能比赛?看两者差值 = A[R] - A[L]
- 差值 = 2,能比赛
那么ans++,然标记3已经用过了,然后移动L和R
(3)L和R能不能比赛?看两者差值 = A[R] - A[L]
- 差值 = 2,能比赛
那么ans++,然标记3已经用过了,然后移动L和R
因为2,3已经用过了,所以L++,直到第一个没有用过的位置
(4)L和R能不能比赛?不能,因为它们是一个人,那么R后移
(4)L和R能不能比赛?能
(5)R已经超出范围,所以结束
实现
class Solution {
int maxPairNum(std::vector<int> arr, int k){
if(k < 0 && arr.size() < 2){
return 0;
}
std::sort(arr.begin(), arr.end());
int res = 0;
int N = arr.size();
int L = 0, R = 0;
std::vector<bool> usedR(N, false); //表示用没有用过
while (L < R && R < N){
if(usedR[L]){ //L跳过已经用过的位置
L++;
}else if(L == R){
R++; // 窗口只有一个人时,R++扩大窗口
}else{
int distance = arr[R] - arr[L];
if(distance == k){
res++;
usedR[R++] = true;
L++;
}else if(distance < k){
R++;
}else{
L++;
}
}
}
return res;
}
};