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
Was this helpful?