适龄的朋友-LeetCode
825. 适龄的朋友
🎯 问题描述(来源于LeetCode)
描述:
在社交媒体网站上有 n 个用户。给你一个整数数组 ages,其中 ages[i] 是第 i 个用户的年龄。
如果满足以下任意条件,则用户 x 不会向用户 y(x != y)发送好友请求:
age[y] <= 0.5 * age[x] + 7age[y] > age[x]age[y] > 100 && age[x] < 100
否则,x 会向 y 发送好友请求。
注意:如果 x 向 y 发送请求,不一定意味着 y 也会向 x 发送请求。
返回总共发出的好友请求数目。
说明:
- 年龄范围在
1到120之间。 n最大为2 * 10^4。
示例:
- 示例 1:
1 | 输入: ages = [16,16] |
- 示例 2:
1 | 输入: ages = [16,17,18] |
💻 解题思路
思路:计数 + 滑动窗口(基于您的代码)
算法步骤
- 因为年龄范围只有 1~120,所以创建一个长度为 121 的计数数组
cnt,统计每个年龄的人数。 - 使用双指针滑动窗口:
age_y表示窗口左边界(年龄最小),cnt_window表示窗口内年龄在[age_y, age_x]之间的人数总和(不包含age_y指针之前的年龄)。- 遍历年龄
age_x从 0 到 120,将当前年龄的人数c加入窗口。 - 当
age_y * 2 <= age_x + 14时(即age_y <= 0.5 * age_x + 7),说明年龄为age_y的人不能向age_x发送请求(因为不满足age[y] > 0.5*age[x]+7),需要将这部分人移出窗口:cnt_window -= cnt[age_y],并将age_y右移。 - 此时,窗口内剩余的人(年龄在
[age_y, age_x]之间)都可以向年龄为age_x的人发送请求。 - 对于每个年龄
age_x的c个人,他们每个人可以向窗口内的所有人发送请求,但 不能向自己发送(因为x != y)。所以新增请求数为c * (cnt_window - 1)?注意:cnt_window包含当前年龄的所有人(包括自己),所以需要减去自身,即c * cnt_window - c(因为每个人不能给自己发,减去c个自身)。但这里还应注意,如果cnt_window只包含age_y到age_x之间的人,且age_x自己也在窗口内,所以减去c正好排除了同年龄的自身请求。 - 累加到
ans。
- 返回
ans。
代码实现(您的代码)
1 | from typing import List |
📊 性能分析
- 时间复杂度:,实际为 ,因为年龄范围固定为 120。
- 空间复杂度:,计数数组大小固定。
思考
该解法非常精妙,利用年龄范围小这一特点,使用计数数组和双指针滑动窗口来统计满足条件的请求数。
关键点在于窗口维护:当 age_y 不满足 age_y > 0.5 * age_x + 7 时,将其移出窗口。此时窗口内所有年龄都满足第一个条件,且因为 age_y 递增,也满足 age_y <= age_x(即第二个条件 age[y] <= age[x] 也自然满足,因为窗口内年龄不超过当前年龄)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






