825. 适龄的朋友
题目描述:
在社交媒体网站上有 n 个用户。给你一个整数数组 ages ,其中 ages[i] 是第 i 个用户的年龄。
如果下述任意一个条件为真,那么用户 x 将不会向用户 y(x != y)发送好友请求:
否则,x 将会向 y 发送一条好友请求。
注意,如果 x 向 y 发送一条好友请求,y 不必也向 x 发送一条好友请求。另外,用户不会向自己发送好友请求。
返回在该社交媒体网站上产生的好友请求总数。
示例:
示例 1:
输入: ages = [16,16]
输出: 2
解释: 2 人互发好友请求。
示例 2:
输入: ages = [16,17,18]
输出: 2
解释: 产生的好友请求为 17 -> 16 ,18 -> 17 。
示例 3:
输入: ages = [20,30,100,110,120]
输出: 3
解释: 产生的好友请求为 110 -> 100 ,120 -> 110 ,120 -> 100 。
提示:
n == ages.length1 <= n <= 2 * 1041 <= ages[i] <= 120
分析:
由题分析,当如下一个条件满足时,则x不会给y发送信息。
-
也就是说当时,
x将给y发送信息。不等式中蕴含条件,也就是说,。我们可以将age数组排序,然后用双指针分别排除不符合条件的人。
复杂度分析:
O(nlogn)。排序需要的时间为 O(nlogn),遍历所有的 ages[x] 以及使用双指针维护答案区间的时间复杂度为 O(n)。
编码:
class Solution {
public int numFriendRequests(int[] ages) {
int len = ages.length;
int ans = 0, start = 0, end = 0;
Arrays.sort(ages);
for (int age : ages) {
if (age < 15) {
continue;
}
while (ages[start] <= 0.5 * age + 7) {
start++;
}
while (end + 1 < len && ages[end + 1] <= age) {
end++;
}
ans += end - start;
}
return ans;
}
}
执行范例:使用前缀和,只需O(n)的时间。
class Solution {
public int numFriendRequests(int[] ages) {
// Arrays.sort(ages);
int l = ages.length, ans = 0;
int[] user = new int[121];
for(int i = 0; i < l; i++){
user[ages[i]] ++;
}
int sum = 0, left = 15; //从15岁才会有朋友,15岁的朋友只有15岁
for(int i = 15; i<121;i++){
if(left <= i*0.5+7){
sum -= user[left];
left ++;
}
if(user[i] == 0){
continue;
}
ans += user[i] * sum + user[i] * (user[i]-1);
sum += user[i];
// System.out.println(i + " " + left+" "+sum);
}
return ans;
}
}