LintCode 895: Friend Request

895. Friend Request

Given an array Ages of length n, where the first i elements represent the age of the individual i. Find total number of friend requests sent by this n person. There are some requirements:

  1. if Age(B) <= (1/2)Age(A) + 7A will not send a request to B.
  2. if Age(B) > Age(A)A will not send a request to B.
  3. if Age(B) < 100 and Age(A) > 100A will not send a request to B.
  4. If it does not satisfy 1,2,3, then A will send a request to B

Example

Example1

Input: Ages = [10,39,50]
Output: 1
Explanation:
Only people of age 50 will send friend requests to people of age 39.

Example2

Input: Ages = [101,79,102]
Output: 1
Explanation:
Only people of age 102 will send friend requests to people of age 101.

Notice

  • Ages.length <= 1000
  • Everyone's age is greater than 0, no larger than 150

Input test data (one parameter per line)How to understand a testcase?

解法1:

这个题目的意思就是一大堆人互相选朋友,每个人都只选比自己小或一样年纪的,但是不能选太小的(底线是要> i / 2 + 7)。另外,101岁或以上的老人只跟100岁或以上的人交朋友,当然对方也要比自己小。

我的解法是先把每个年龄的个数存到distribution数组里面。然后我们可以看出1..100岁和101..150岁的情况不一样,应该分开处理。这样,时间复杂度就优化到O(150*150)以内了。

需要注意的几点:
1) 同一个年龄段彼此也要交朋狗友,reqCount += distribution[i] * (distribution[i] - 1);
2) 每个年龄段的每一个人的交朋友数addCount就是比他小的那些人的数目总和。而该年龄段每个人的情况都一样,所以addCount还要乘以distribution[i]。
3) 最容易忽视的一个地方就是非常小的小孩彼此之间不能交朋友,因为对方的年纪不满足>i/2+7。

class Solution {
public:
    /**
     * @param ages: The ages
     * @return: The answer
     */
    int friendRequest(vector<int> &ages) {
        int n = ages.size();
        vector<int> distribution(151, 0);
        for (int i = 0; i < n; ++i) {
            distribution[ages[i]]++;
        }
        
        int reqCount = 0;
        for (int i = 1; i <= 100; ++i) {
            if (distribution[i] == 0) continue;
            int lowLimit = i / 2 + 7;
            if (i > lowLimit) reqCount += distribution[i] * (distribution[i] - 1);
            int addCount = 0;
            for (int j = lowLimit + 1; j < i; ++j) {
                if (distribution[j] == 0) continue;
                addCount += distribution[j];
            }
            reqCount += addCount * distribution[i];
        }

        for (int i = 101; i <= 150; ++i) {
            if (distribution[i] == 0) continue;
            reqCount += distribution[i] * (distribution[i] - 1);
            int addCount = 0;
            for (int j = 100; j < i; ++j) {
                if (distribution[j] == 0) continue;
                addCount += distribution[j];
            }
            reqCount += addCount * distribution[i];
        }
        
        return reqCount;
    }
};

解法2:解法1用presums数组优化到O(150)。

class Solution {
public:
    /**
     * @param ages: The ages
     * @return: The answer
     */
    int friendRequest(vector<int> &ages) {
        int n = ages.size();
        vector<int> distribution(151, 0);
        for (int i = 0; i < n; ++i) {
            distribution[ages[i]]++;
        }
        
        vector<int> presums(151, 0);
        for (int i = 1; i < 151; ++i) {
            presums[i] = presums[i - 1] + distribution[i];
        }
        
        int reqCount = 0;
        for (int i = 1; i <= 100; ++i) {
            if (distribution[i] == 0) continue;
            int lowLimit = i / 2 + 7;
            if (i > lowLimit) {
                reqCount += distribution[i] * (distribution[i] - 1);
                reqCount += (presums[i - 1] - presums[lowLimit]) * distribution[i];    
            }
        }

        for (int i = 101; i <= 150; ++i) {
            if (distribution[i] == 0) continue;
            reqCount += distribution[i] * (distribution[i] - 1);
            reqCount += (presums[i - 1] - presums[99]) * distribution[i];
        }
        
        return reqCount;
    }
};

解法3:下面这个是标准解法。不过时间复杂度是O(n*n)。如果n很大会比较慢。

class Solution {
public:
    /**
     * @param ages: The ages
     * @return: The answer
     */
    int friendRequest(vector<int> &ages) {
        int ans = 0;
        for(int i = 0; i < ages.size(); i++) {
            for(int j = 0; j < ages.size(); j++) {
                if(i == j) {
                    continue;
                }
                int A = ages[i];
                int B = ages[j];
                if(B <= A && B > A / 2 + 7 && !(B < 100 && A > 100)) {
                    ans++;
                }
            }
        }
        return ans;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值