题目描述:
人们会互相发送好友请求,现在给定一个包含有他们年龄的数组,ages[i] 表示第 i 个人的年龄。
当满足以下条件时,A 不能给 B(A、B不为同一人)发送好友请求:
- age[B] <= 0.5 * age[A] + 7
- age[B] > age[A]
- age[B] > 100 && age[A] < 100
否则,A 可以给 B 发送好友请求。
注意如果 A 向 B 发出了请求,不等于 B 也一定会向 A 发出请求。而且,人们不会给自己发送好友请求。
求总共会发出多少份好友请求?
题中示例不再展示
说明:
- 1 <= ages.length <= 20000.
- 1 <= ages[i] <= 120.
解题思路:
首先我们来分析一下A能够 \color{red}能够能够发送好友请求给B的情况,(注意题中给的规则是A不能发给B的情况)
首先由第一条规则可知,age[B] > 0.5 * age[A] + 7
第二条规则可知,age[B] <= age[A]
第三条规则正好与第条规则耦合了,所以不需要了,满足第二条一定会满足第三条。(可以琢磨一下)
因此我们得到了两条A能够能够发送好友请求给B的规则,age[B] > 0.5 * age[A] + 7,age[B] <= age[A]。
接着就是如何计算所有可发送的请求总数了。可能会有很大一部分的人选择扫描一遍age数组,计算每个人能够发出的好友请求数,然后再求和即可。蛋式age的大小在2W左右,处理起来非常麻烦。如果我们把所有年龄相同的人统计起来,这最多只有120情况,因此我们可以计算 每一个年龄发送给另一个年龄的好友请求数,然后求和。这样就大大的降低了时间复杂度!!!
解题代码:
public static int fasong(Integer[] ages){
// 记录各个年龄的人数
int[] mun = new int[121];
for(int age :ages){
mun[age] ++;
}
// 记录请求份数
int count = 0;
for(int i = 1; i <=120;i++){
if(mun[i]==0){continue;}
for (int j = 0; j <=120;j++){
if(j<=0.5*i+7){
continue;
}
if(j>i){
continue;
}
if(j>100&&i<100){
continue;
}
if(i==j){count+=mun[i]*(mun[i]-1);continue;}
count+=mun[i]*mun[j];
}
}
return count ;
}
个人感悟:
我在拿到这个题的时候是非常高兴的,因为初次见面觉得它太简单啦,但是当第一次提交遇到因为运行时间过长而没有通过时,我意识到这没有那么简单,将某一个人与某个人之间的发送交友请求的事件,转化为一个年龄与另一个年龄的事件,这样大大减少时间复杂度,当然还要注意同一年龄可能有多个人,他们是不是可以交朋友也是需要考虑的;
今天我能遇到这个题是我的幸运,今天随机刷到的第一个题,让我看题目就已经愁思千缕,不信也来挑战一下,欢迎大神教一下