Friends Of Appropriate Ages(数学逻辑

Some people will make friend requests. The list of their ages is given and ages[i] is the age of the ith person.

Person A will NOT friend request person B (B != A) if any of the following conditions are true:

  • age[B]

    <

    = 0.5 * age[A] + 7

  • age[B]

    >

    age[A]

  • age[B]

    >

    100

    &

    &

    age[A]

    <

    100

Otherwise, A will friend request B.

Note that if A requests B, B does not necessarily request A. Also, people will not friend request themselves.

How many total friend requests are made?

Example 1:

Input: [16,16]
Output: 2
Explanation: 2 people friend request each other.

Example 2:

Input: [16,17,18]
Output: 2
Explanation: Friend requests are made 17 -> 16, 18 -> 17.

Example 3:

Input: [20,30,100,110,120]
Output: 
Explanation: Friend requests are made 110 -> 100, 120 -> 110, 120 -> 100.

Notes:

1 <= ages.length <= 20000.
1 <= ages[i] <= 120.

分析

方法1 年级120内,map存每个age的个数。然后2个for遍历所有数字,相乘(注意= 是*cnt(b)-1)

方法2 用array和和数学公式。a,b 之间范围的和相减,[a, b = a/2 +7]

class Solution {
     public int numFriendRequests(int[] ages) {

        int map[] = new int[121];
        for(int age: ages){
            map[age] ++;
        }
        int ret = 0;
        for(int i = 1; i <= 120; i ++){
            for(int j = 1; j <= 120; j ++){//次数需要从1开始而不是从i, 因为朋友关系是相互的。所以需要前去后来
                if(valid(i,j)){
                    ret += map[i] * (i == j ? map[j] - 1 : map[j]);
                }
            }

        }
        return ret;
    }
    public boolean valid(int a, int b) {
        return !(b <= 0.5 * a + 7 || b > a || (b > 100 && a < 100)); //其实条件2和3重复了
    }
}
class Solution {
    public int numFriendRequests(int[] ages) { //优化2,另一数组sums记录范围,这样计算count不用2 for,直接找范围内个数即可
        int[] nums = new int[121], sums = new int[121];
        for (int age : ages) nums[age]++; //记录每个年龄多少人
        for (int i = 1; i < sums.length; i++) sums[i] = sums[i - 1] + nums[i]; //相当于记录小于i的有多少人
        int res = 0;
        for (int i = 15; i < sums.length; i++) { //i / 2 + 7 < i -> i>14
            if (nums[i] == 0) continue; //0一定要跳过,否则后面是负数
            int count = sums[i] - sums[i / 2 + 7]; //(i/2+7, i] 有多少个
            res += (count - 1) * nums[i]; //不能和自身request
        }
        return res;
    }
}

Last updated