当前位置:网站首页>leetcode825. 适龄的朋友
leetcode825. 适龄的朋友
2022-07-04 06:33:00 【2021dragon】
LeetCode系列文章
一、题目描述
在社交媒体网站上有 n n n 个用户。给你一个整数数组 a g e s ages ages,其中 a g e s [ i ] ( 1 ≤ a g e s [ i ] ≤ 120 ) ages[i](1\leq ages[i] \leq 120) ages[i](1≤ages[i]≤120) 是第 i i i 个用户的年龄。
如果下述任意一个条件为真,那么用户 x x x 将不会向用户 y y y 发送好友请求:
- a g e s [ y ] ≤ 0.5 × a g e s [ x ] + 7 ages[y]\leq0.5\times ages[x]+7 ages[y]≤0.5×ages[x]+7
- a g e s [ y ] > a g e s [ x ] ages[y]>ages[x] ages[y]>ages[x]
- a g e s [ y ] > 100 & & a g e s [ x ] < 100 ages[y]>100\&\&ages[x]<100 ages[y]>100&&ages[x]<100
否则, x x x 将会向 y y y 发送一条好友请求。
注意,如果 x x x 向 y y y 发送一条好友请求, y y y 不必也向 x x x 发送一条好友请求。另外,用户不会向自己发送好友请求。
返回在该社交媒体网站上产生的好友请求总数。
二、示例
输入: ages = [16, 16]
输出: 2
解释: 2人互发好友请求。
三、主体思路
1、暴力解法
采用暴力解法解决该题目是非常简单的,要判断一个用户能够给哪些用户发送好友请求,只需要遍历这 n − 1 n-1 n−1(不包括自己)个用户,依次判断是否满足发送好友请求的条件即可。
很明显这种暴力解法的时间复杂度是 O ( N 2 ) O(N^2) O(N2),当用户数据量过大时计算消耗的时间就会暴增,因此这种解法是不推荐的。
2、排序+双指针
仔细观察题目所给的三个条件,你会发现条件三其实是蕴含在条件二当中的,如果满足了条件三那就一定满足条件二,因此只要不满足前两个条件,那么用户 x x x 就能向用户 y y y 发送好友请求,也就是用户 y y y 需要满足: 0.5 × a g e s [ x ] + 7 < a g e s [ y ] ≤ a g e s [ x ] 0.5\times ages[x]+7<ages[y]\leq ages[x] 0.5×ages[x]+7<ages[y]≤ages[x]
将这个关系用数轴表示如下:
如果存在满足要求的用户 y y y,那么 0.5 × x + 7 < x 0.5\times x+7<x 0.5×x+7<x,即 x > 14 x > 14 x>14。也就是说,如果一个用户的年龄小于等于14,那么该用户将不能向任何用户发送好友请求。
现在看来,要知道用户 x x x 能够向哪些用户 y y y 发送好友请求,实际就需要求出该数轴上对应的左右边界,年龄位于该区域内的用户就是用户 x x x 能够向其发送好友请求的用户。
在寻找左右边界时可以用 l e f t left left 和 r i g h t right right 表示左右边界的下标(双指针),如果左右都采用闭区间,即 l e f t left left 指向的是第一个满足要求的用户, r i g h t right right 指向的是最后一个满足要求的用户,那么最终 r i g h t − l e f t right-left right−left 的值就是满足要求的用户 y y y 的个数。(注意:这里不是 r i g h t − l e f t + 1 right-left+1 right−left+1,因为用户 x x x 本身也是在该区域当中的,但用户 x x x 不会向自己发送好友请求)
因此解题步骤如下:
- 对所给 n n n 个用户的年龄进行排序。
- 依次遍历这 n n n 个用户的年龄。
- 在遍历用户时,如果该用户的年龄小于等于14,则该用户能够向外发送好友请求的个数为0;如果该用户的年龄大于14,则通过双指针找到满足发送要求的区域,进而得出该用户能够向外发送的好友请求的个数。
- 最后将每个用户能够向外发送的好友请求的个数进行累加即可。
特别注意,在通过双指针确定满足要求的年龄区域时,只有第一次需要在 n n n 个用户的基础上从头进行查找。而后续在确定区域时,区域的左右边界只需要在上一个用户的左右边界的基础上向后进行查找即可。因为 0.5 × x + 7 0.5\times x+7 0.5×x+7 与 x x x 是线性的关系,当 x x x 增大时, 0.5 × x + 7 0.5\times x+7 0.5×x+7 的值也会增大,因此我们无需再判断上一个用户的 l e f t left left 指针之前的用户年龄是否在本次限定的区域当中。
3、计数排序+前缀和
仔细观察你会发现题目给定用户的年龄是在 [ 1 , 120 ] [1, 120] [1,120] 范围内的,因此我们可以采用计数排序统计各个年龄段用户的个数并进行排序。
比如我们将排序结果存储到 c n t cnt cnt 数组当中,此时 c n t [ a g e ] cnt[age] cnt[age] 就表示年龄为 a g e age age 的用户个数,而每一个年龄为 a g e age age 的用户能够向外发送的好友请求的数量就是: ( ∑ i = 0.5 × a g e + 8 a g e c n t [ i ] ) − 1 (\sum_{i=0.5\times age+8}^{age}cnt[i])-1 (∑i=0.5×age+8agecnt[i])−1,其中减一是因为用户不会向自己发送好友请求。
为了避免每次都要遍历 c n t cnt cnt 数组进行求和,我们可以计算出 c n t cnt cnt 数组的前缀和数组 p r e pre pre, p r e [ a g e ] pre[age] pre[age] 代表的就是年龄段位于1 ~ age的用户个数: p r e [ a g e ] = ∑ i = 1 a g e c n t [ i ] pre[age]=\sum_{i=1}^{age}cnt[i] pre[age]=∑i=1agecnt[i]。
此时每一个年龄为 a g e age age 的用户能够向外发送的好友请求的数量就可以写为: p r e [ a g e ] − p r e [ 0.5 × a g e + 7 ] − 1 pre[age]-pre[0.5\times age+7]-1 pre[age]−pre[0.5×age+7]−1
此时我们就能够在 O ( 1 ) O(1) O(1) 的时间内计算出一个年龄为 a g e age age 的用户能够向外发送的好友请求的数量,将该值乘以 c n t [ a g e ] cnt[age] cnt[age] 就是该年龄段的所有用户总计能够向外发送的好友请求的数量。
因此解题步骤如下:
- 通过计数排序统计每个年龄段的用户个数。
- 计数出 c n t cnt cnt 数组的前缀和数组 p r e pre pre。
- 通过 ( p r e [ a g e ] − p r e [ 0.5 × a g e + 7 ] − 1 ) × c n t [ a g e ] (pre[age]-pre[0.5\times age+7]-1)\times cnt[age] (pre[age]−pre[0.5×age+7]−1)×cnt[age] 公式计算出每个年龄段的用户总计能够向外发送的好友请求的数量,将其进行累加就是最终结果。
四、代码实现
1、暴力解法
2、排序+双指针
3、计数排序+前缀和
边栏推荐
- 微信小程序使用rich-text中图片宽度超出问题
- How to realize multi account login of video platform members
- Wechat applet scroll view component scrollable view area
- ORICO ORICO outdoor power experience, lightweight and portable, the most convenient office charging station
- How to implement cross domain requests
- JSON Web Token----JWT和传统session登录认证对比
- [March 3, 2019] MAC starts redis
- Average two numbers
- The sorting in C language realizes the number sorting method from small to large
- C實現貪吃蛇小遊戲
猜你喜欢
Learning multi-level structural information for small organ segmentation
List of top ten professional skills required for data science work
[untitled]
Common usage of time library
Layoutmanager layout manager: flowlayout, borderlayout, GridLayout, gridbaglayout, CardLayout, BoxLayout
Mysql 45讲学习笔记(七)行锁
Json Web token - jwt vs. Traditional session login Authentication
GoogleChromePortable 谷歌chrome浏览器便携版官网下载方式
[backpack DP] backpack problem
Native Cloud - SSH articles must be read on Cloud (used for Remote Login to Cloud Server)
随机推荐
The width of the picture in rich text used by wechat applet exceeds the problem
Mysql 45讲学习笔记(十二)MySQL会“抖”一下
C # symmetric encryption (AES encryption) ciphertext results generated each time, different ideas, code sharing
8. Factory method
[MySQL] introduction, function, creation, view, deletion and modification of database view (with exercises)
uniapp 自定義環境變量
7. Agency mode
27-31. Dependency transitivity, principle
Is the insurance annuity product worth buying? Is there a hole?
Arcpy 利用updatelayer函数改变图层的符号系统
JSON web token -- comparison between JWT and traditional session login authentication
Mysql 45讲学习笔记(十四)count(*)
STM32 单片机ADC 电压计算
SQL injection SQL lab 11~22
Realize IIC data / instruction interaction with micro batg135
How to use multithreading to export excel under massive data? Source code attached!
4G wireless all network solar hydrological equipment power monitoring system bms110
11. Dimitt's law
The solution of win11 taskbar right click without Task Manager - add win11 taskbar right click function
Fundamentals of SQL database operation