【力扣时间】【825】【中等】适龄的朋友

额……首先,这道题我是做出来了,只是解法过于简单粗暴,所以参考价值不大。
本着一半是为了将来的我能够看到进步的原则,还是记录一下吧。

1、先看题

点我

题目不短也不长,一边说了题意也一边铺了烟雾弹。
往下看吧。

2、审题

这道题有很多地方讲解地不明不白的,虽然你可能能够知道要做些什么,但却有些细节让你不好动手。

且听我慢慢分解吧。

  1. 题目给出了3个条件,但实际上只有2个。稍微动下脑子就会发现,条件3已结被条件2涵盖进去了。
  2. 每个条件都是从x向y发送请求的角度出发的。而满足任一条件,则不会发出请求
  3. 如果 x 向 y 发送一条好友请求,y 不必也向 x 发送一条好友请求。这句话就是一烟雾弹,实际的理解是如果满足条件,则x可以向y发请求。然后换过来考虑,如果y也符合向x发请求的条件,那么它也可以发出请求。
  4. case1指出,如果两个人的年龄相同,则可以互相发送请求,算作2条。等于是上面一条要点的应用。

我在厘清了条件后,就开始动手了,毕竟题目就已经给清了条件语句,所以实现起来似乎没什么困难的。
直到我遇上了一堆超时,修修改改提交成功,看到耗时排名后我才知道—— too native!

3、思路

我花了写时间在厘清题目给出的条件上。

首先我们可以发现,在条件2的基础上,条件3就是废话。条件2规定了x的年龄必须大于等于y。
在此基础上,我想到了首先对整个队列进行排序,这样就可以保证单向的比较上,年龄大于等于的要求可以忽略掉。

其次是条件1,当你以x的角度出发去比较时,由于x的年龄是固定的,所以0.5 * age[x] + 7将始终是固定值,则我们可以根据此为标准,快速的得出哪些人可以发出请求。
同时,由于队列已经是递增的了,我们也能知道何时跳出比较。

想到这,整体思路就成形了。

4、开工!

class Solution {
    public int numFriendRequests(int[] ages) {
        int ans = 0;
        Arrays.sort(ages);

        for (int i = ages.length - 1; i >= 1; i--) {
            int ageLine = (int) (0.5 * ages[i] + 7);

            for (int j = i - 1; j >= 0; j--) {
				//年龄不够后,跳出循环
                if (ages[j] <= ageLine) {
                    break;
                }

                ans++;
                //年龄一致时可以互粉
                if (ages[i] == ages[j]) {
                    ans++;
                }
            }
        }

        return ans;
    }
}

看着很简洁是吧。
但这解法除了好想好写外就是个jb……

5、解读

跳过,没脸讲解什么,下面会放出大牛们的精彩解法,大家学那些吧。

你可得给劲了,将来的我……

6、提交

在这里插入图片描述
毕竟是接近O(n2) 的实现,就这样吧……

7、大牛们来了

快进到开脑洞

这里依旧是有请三叶大佬吧。

人不仅解法出色,解释清楚,还画出了漂亮的图。
知道差距了吧
大佬提供了两种解法,双指针前缀和

双指针想法与我的类似,但在计算单个人的可交友数量时更加快捷,单个用户的耗时为O(logN),于是可以让整体的时间复杂度来到O(NlogN)

但你以为这就完了?
前缀和让你小刀划屁股——开开眼!整点通辽话
具体实现和思路看大佬讲解吧……

前缀和实际上是我比较擅长的解法,毕竟空间换时间的思路很符合我。实际上在发现我的解法耗时奇差时,我就想过通过前缀和的思路去优化,但始终没有绕过弯。
现在看来,我始终是在ages[] 上考虑应用前缀和,但大牛们却是在年龄上使用。从这一点就直接分出来胜负。

8、总结

虽然是中等题,但却也让我学到了很多啊。

现实中不乏牛人,但更多的可能只是像我这样的泛泛之辈……
尽管我们努力可能也永远够不大牛们的后脚跟,但如果不努力,你连努力的凡人也无法触及。

所以,加油吧社畜

与各位凡人社畜,共勉。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值