leetcode825. 适龄的朋友_leetcode

LeetCode系列文章

文章目录

一、题目描述

leetcode825. 适龄的朋友_动态规划_02 个用户。给你一个整数数组 leetcode825. 适龄的朋友_排序算法_03,其中 leetcode825. 适龄的朋友_c++_04 是第 leetcode825. 适龄的朋友_leetcode_05 个用户的年龄。

  如果下述任意一个条件为真,那么用户 leetcode825. 适龄的朋友_算法_06 将不会向用户 leetcode825. 适龄的朋友_动态规划_07

  • leetcode825. 适龄的朋友_排序算法_08
  • leetcode825. 适龄的朋友_leetcode_09
  • leetcode825. 适龄的朋友_排序算法_10

leetcode825. 适龄的朋友_算法_06 将会向 leetcode825. 适龄的朋友_动态规划_07 发送一条好友请求。

  注意,如果 leetcode825. 适龄的朋友_算法_06leetcode825. 适龄的朋友_动态规划_07 发送一条好友请求,leetcode825. 适龄的朋友_动态规划_07 不必也向 leetcode825. 适龄的朋友_算法_06 发送一条好友请求。另外,用户不会向自己发送好友请求。

  返回在该社交媒体网站上产生的好友请求总数。

二、示例

  输入: ages = [16, 16]
  输出: 2

  解释: 2人互发好友请求。

三、主体思路

1、暴力解法

leetcode825. 适龄的朋友_排序算法_17(不包括自己)个用户,依次判断是否满足发送好友请求的条件即可。

  很明显这种暴力解法的时间复杂度是 leetcode825. 适龄的朋友_动态规划_18,当用户数据量过大时计算消耗的时间就会暴增,因此这种解法是不推荐的。

2、排序+双指针

leetcode825. 适龄的朋友_leetcode_19 就能向用户 leetcode825. 适龄的朋友_算法_20 发送好友请求,也就是用户 leetcode825. 适龄的朋友_算法_20 需要满足:leetcode825. 适龄的朋友_排序算法_22


将这个关系用数轴表示如下:

leetcode825. 适龄的朋友_算法_23


  如果存在满足要求的用户 leetcode825. 适龄的朋友_算法_20,那么 leetcode825. 适龄的朋友_leetcode_25,即 leetcode825. 适龄的朋友_排序算法_26。也就是说,如果一个用户的年龄小于等于14,那么该用户将不能向任何用户发送好友请求。leetcode825. 适龄的朋友_leetcode_19 能够向哪些用户 leetcode825. 适龄的朋友_算法_20 发送好友请求,实际就需要求出该数轴上对应的左右边界,年龄位于该区域内的用户就是用户 leetcode825. 适龄的朋友_leetcode_19 能够向其发送好友请求的用户。


  在寻找左右边界时可以用 leetcode825. 适龄的朋友_c++_30leetcode825. 适龄的朋友_排序算法_31 表示左右边界的下标(双指针),如果左右都采用闭区间,即 leetcode825. 适龄的朋友_c++_30 指向的是第一个满足要求的用户,leetcode825. 适龄的朋友_排序算法_31 指向的是最后一个满足要求的用户,那么最终 leetcode825. 适龄的朋友_排序算法_34 的值就是满足要求的用户 leetcode825. 适龄的朋友_算法_20 的个数。(注意:这里不是 leetcode825. 适龄的朋友_算法_36,因为用户 leetcode825. 适龄的朋友_leetcode_19 本身也是在该区域当中的,但用户 leetcode825. 适龄的朋友_leetcode_19 不会向自己发送好友请求)

leetcode825. 适龄的朋友_leetcode_39


因此解题步骤如下:

  • 对所给leetcode825. 适龄的朋友_动态规划_02
  • 依次遍历这leetcode825. 适龄的朋友_动态规划_02
  • 在遍历用户时,如果该用户的年龄小于等于14,则该用户能够向外发送好友请求的个数为0;如果该用户的年龄大于14,则通过双指针找到满足发送要求的区域,进而得出该用户能够向外发送的好友请求的个数。
  • 最后将每个用户能够向外发送的好友请求的个数进行累加即可。

leetcode825. 适龄的朋友_c++_42 个用户的基础上从头进行查找。而后续在确定区域时,区域的左右边界只需要在上一个用户的左右边界的基础上向后进行查找即可。因为 leetcode825. 适龄的朋友_leetcode_43leetcode825. 适龄的朋友_leetcode_19 是线性的关系,当 leetcode825. 适龄的朋友_leetcode_19 增大时,leetcode825. 适龄的朋友_leetcode_43 的值也会增大,因此我们无需再判断上一个用户的 leetcode825. 适龄的朋友_c++_30

3、计数排序+前缀和

leetcode825. 适龄的朋友_算法_48 范围内的,因此我们可以采用计数排序统计各个年龄段用户的个数并进行排序。


  比如我们将排序结果存储到 leetcode825. 适龄的朋友_算法_49 数组当中,此时 leetcode825. 适龄的朋友_算法_50 就表示年龄为 leetcode825. 适龄的朋友_动态规划_51 的用户个数,而每一个年龄为 leetcode825. 适龄的朋友_动态规划_51 的用户能够向外发送的好友请求的数量就是:leetcode825. 适龄的朋友_算法_53,其中减一是因为用户不会向自己发送好友请求。


  为了避免每次都要遍历 leetcode825. 适龄的朋友_算法_49 数组进行求和,我们可以计算出 leetcode825. 适龄的朋友_算法_49 数组的前缀和数组 leetcode825. 适龄的朋友_排序算法_56leetcode825. 适龄的朋友_c++_57 代表的就是年龄段位于1 ~ age的用户个数:leetcode825. 适龄的朋友_动态规划_58


  此时每一个年龄为 leetcode825. 适龄的朋友_动态规划_51 的用户能够向外发送的好友请求的数量就可以写为:leetcode825. 适龄的朋友_leetcode_60

leetcode825. 适龄的朋友_leetcode_61


  此时我们就能够在 leetcode825. 适龄的朋友_算法_62 的时间内计算出一个年龄为 leetcode825. 适龄的朋友_动态规划_51 的用户能够向外发送的好友请求的数量,将该值乘以 leetcode825. 适龄的朋友_算法_50

因此解题步骤如下:

  • 通过计数排序统计每个年龄段的用户个数。
  • 计数出leetcode825. 适龄的朋友_动态规划_65数组的前缀和数组leetcode825. 适龄的朋友_leetcode_66
  • 通过leetcode825. 适龄的朋友_leetcode_67

四、代码实现

1、暴力解法

leetcode825. 适龄的朋友_c++_68

2、排序+双指针

leetcode825. 适龄的朋友_排序算法_69

3、计数排序+前缀和

leetcode825. 适龄的朋友_c++_70