825.适龄的朋友
题目描述
思路
排序+双指针
根据题目给定的三个条件,不难发现,第三个条件是蕴含在第二个条件中的,即如果条件3满足,条件2一定满足。因此,当条件1、2均不满足时,用户x就会向y发送好友请求。也就是说y需要满足条件:
0.5
∗
a
g
e
s
[
x
]
+
7
<
a
g
e
s
[
y
]
≤
a
g
e
s
[
x
]
0.5*ages[x] + 7 < ages[y] ≤ ages[x]
0.5∗ages[x]+7<ages[y]≤ages[x]
当ages[x]≤14时,不存在满足条件的ages[y]。所以只需要考虑ages[x]≥15的情况。
当ages[x]增加时,ages[y]的范围左右边界均单调递增,因此可以对ages进行升序排序,就可以在遍历ages[x]的同时,使用两个指针left和right维护满足要求的左右边界。当x往后移动一个位置:
- 如果左边界指针left指向的元素不满足ages[left]≥ages[x]*0.5+7,则左边界向后移动一个位置;
- 如果右边界指针right指向的元素满足ages[right+1]≤ages[x],则右边界向后移动一个位置。
如此一来,[left, right]就是满足要求的y的下标。另外,x本身一定在[left,right]之间,因此x发送的好友请求数为[left, right]的区间长度-1。
并将每个x对应的结果累加,即可得到答案。
Python实现
class Solution:
def numFriendRequests(self, ages: List[int]) -> int:
n = len(ages)
ages.sort()
ans = left = right = 0
for age in ages:
if age <= 14:
continue
while ages[left] <= 0.5 * age + 7:
left += 1
while right + 1 < n and ages[right + 1] <= age:
right += 1
ans += right - left
return ans
Java实现
class Solution {
public int numFriendRequests(int[] ages) {
int n = ages.length;
Arrays.sort(ages);
int ans = 0, left = 0, right = 0;
for (int age: ages) {
if (age <= 14) {
continue;
}
while (ages[left] <= 0.5*age + 7) {
++left;
}
while (right + 1 < n && ages[right + 1] <= age) {
++right;
}
ans += right - left;
}
return ans;
}
}