当前位置:网站首页>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、计数排序+前缀和
边栏推荐
- 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?
- tars源码分析之3
- How to help others effectively
- What is tweeman's law?
- Code rant: from hard coding to configurable, rule engine, low code DSL complexity clock
- tars源码分析之6
- How to implement cross domain requests
- Displaying currency in Indian numbering format
- QT releases multilingual International Translation
- SQL join, left join, right join usage
猜你喜欢
Matlab remainder
Mysql 45讲学习笔记(七)行锁
The solution of win11 taskbar right click without Task Manager - add win11 taskbar right click function
How to avoid JVM memory leakage?
Appium基础 — APPium安装(二)
C language - Blue Bridge Cup - Snake filling
C realize Snake games
云原生——上云必读之SSH篇(常用于远程登录云服务器)
R统计绘图-随机森林分类分析及物种丰度差异检验组合图
Which water in the environment needs water quality monitoring
随机推荐
C language - Blue Bridge Cup - Snake filling
Mysql 45讲学习笔记(十二)MySQL会“抖”一下
What is Gibson's law?
Reading notes of Clickhouse principle analysis and Application Practice (4)
27-31. Dependency transitivity, principle
tars源码分析之4
C language exercises (recursion)
Background and current situation of domestic CDN acceleration
Common usage of time library
Internet of things protocol ZigBee ZigBee module uses the concept of protocol stack
Software keywords and process information intercepted by Golden Shield video player
Is the insurance annuity product worth buying? Is there a hole?
雲原生——上雲必讀之SSH篇(常用於遠程登錄雲服務器)
对List进行排序工具类,可以对字符串排序
Another company raised the price of SAIC Roewe new energy products from March 1
Can the out of sequence message complete TCP three handshakes
QT qtablewidget table column top requirements ideas and codes
Fast power (template)
The solution of win11 taskbar right click without Task Manager - add win11 taskbar right click function
2022.7.2-----leetcode. eight hundred and seventy-one