算法练习:适龄朋友问题

题目描述:

人们会互相发送好友请求,现在给定一个包含有他们年龄的数组,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 ;
    }

个人感悟:

我在拿到这个题的时候是非常高兴的,因为初次见面觉得它太简单啦,但是当第一次提交遇到因为运行时间过长而没有通过时,我意识到这没有那么简单,将某一个人与某个人之间的发送交友请求的事件,转化为一个年龄与另一个年龄的事件,这样大大减少时间复杂度,当然还要注意同一年龄可能有多个人,他们是不是可以交朋友也是需要考虑的;

今天我能遇到这个题是我的幸运,今天随机刷到的第一个题,让我看题目就已经愁思千缕,不信也来挑战一下,欢迎大神教一下

460. LFU缓存

发布了71 篇原创文章 · 获赞 14 · 访问量 5611

猜你喜欢

转载自blog.csdn.net/flying_hengfei/article/details/105335544