当前位置:网站首页>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、计数排序+前缀和
边栏推荐
- uniapp 自定義環境變量
- Software keywords and process information intercepted by Golden Shield video player
- Another company raised the price of SAIC Roewe new energy products from March 1
- The width of the picture in rich text used by wechat applet exceeds the problem
- [March 3, 2019] MAC starts redis
- Learn about the Internet of things protocol WiFi ZigBee Bluetooth, etc. --- WiFi and WiFi protocols start from WiFi. What do we need to know about WiFi protocol itself?
- Background and current situation of domestic CDN acceleration
- GoogleChromePortable 谷歌chrome浏览器便携版官网下载方式
- tars源码分析之4
- 树形dp
猜你喜欢
Wechat applet scroll view component scrollable view area
746. Climb stairs with minimum cost
27-31. Dependency transitivity, principle
C # symmetric encryption (AES encryption) ciphertext results generated each time, different ideas, code sharing
C réaliser des jeux de serpents gourmands
QT get random color value and set label background color code
Matlab remainder
Cloud native - SSH article that must be read on the cloud (commonly used for remote login to ECS)
Bicolor case
Google Chrome Portable Google Chrome browser portable version official website download method
随机推荐
Mysql 45讲学习笔记(十)force index
ADC voltage calculation of STM32 single chip microcomputer
Analysis of tars source code 5
What is the "relative dilemma" in cognitive fallacy?
如何实现视频平台会员多账号登录
Mysql 45讲学习笔记(六)全局锁
uniapp 自定義環境變量
Tar source code analysis Part 3
云原生——上云必读之SSH篇(常用于远程登录云服务器)
ABAP:OOALV实现增删改查功能
Considerations for testing a website
对List进行排序工具类,可以对字符串排序
运算符<< >>傻瓜式测试用例
[March 3, 2019] MAC starts redis
How to choose the middle-aged crisis of the testing post? Stick to it or find another way out? See below
8. Factory method
thread priority
【问题记录】03 连接MySQL数据库提示:1040 Too many connections
Common usage of time library
Appium foundation - appium installation (II)