每日一题-适龄的朋友(中等)

302 阅读2分钟

825. 适龄的朋友

题目描述:

在社交媒体网站上有 n 个用户。给你一个整数数组 ages ,其中 ages[i] 是第 i 个用户的年龄。

如果下述任意一个条件为真,那么用户 x 将不会向用户 yx != y)发送好友请求:

  • age[y]<=0.5age[x]+7age[y] <= 0.5 * age[x] + 7
  • age[y]>age[x]age[y] > age[x]
  • age[y]>100&&age[x]<100age[y] > 100 \&\& age[x] < 100

否则,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 -> 100120 -> 110120 -> 100

提示:

  • n == ages.length
  • 1 <= n <= 2 * 104
  • 1 <= ages[i] <= 120

分析:

由题分析,当如下一个条件满足时,则x不会给y发送信息。

  • age[y]<=0.5age[x]+7age[y] <= 0.5 * age[x] + 7
  • age[y]>age[x]age[y] > age[x]
  • age[y]>100&&age[x]<100age[y] > 100 \&\& age[x] < 100 也就是说当0.5age[x]+7<age[y]age[x] 0.5 * age[x] + 7<age[y] \leq age[x]时,x将给y发送信息。不等式中蕴含条件0.5age[x]+7<age[x] 0.5 * age[x] + 7< age[x],也就是说,age[x]>14age[x]>14。我们可以将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;

    }
}

题目链接