Some people will make friend requests. The list of their ages is given and ages[i]
is the age of the ith person. html
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.app
Note that if A requests B, B does not necessarily request A. Also, people will not friend request themselves.post
How many total friend requests are made?優化
Example 1:url
Input: [16,16] Output: 2 Explanation: 2 people friend request each other.
Example 2:spa
Input: [16,17,18] Output: 2 Explanation: Friend requests are made 17 -> 16, 18 -> 17.
Example 3:code
Input: [20,30,100,110,120] Output: Explanation: Friend requests are made 110 -> 100, 120 -> 110, 120 -> 100.
Notes:htm
1 <= ages.length <= 20000
.1 <= ages[i] <= 120
.
這道題是關於好友申請的,說是若A想要加B的好友,下面三個條件一個都不能知足才行:blog
1. B的年齡小於等於A的年齡的一半加7。
2. B的年齡大於A的年齡。
3. B大於100歲,且A小於100歲。
實際上若是你仔細看條件3,B要是大於100歲,A小於100歲,那麼B必定大於A,這就跟條件2重複了,徹底不懂出題者的想法。無論了,強行解題唄。那麼因爲只能給比本身小的人發送好友請求,那麼博主就想到咱們能夠獻給全部人拍個序,而後從後往前遍歷,對於每一個遍歷到的人,再遍歷全部比他小的人,這樣第二個條件就知足了,前面說了,第三個條件能夠不用管了,那麼只要看知足第一個條件就能夠了,還有要注意的,假如兩我的年齡相同,那麼知足了前兩個條件後,實際上是能夠互粉的,因此要額外的加1,這樣纔不會漏掉任何一個好友申請,參見代碼以下:
解法一:
class Solution { public: int numFriendRequests(vector<int>& ages) { int res = 0, n = ages.size(); sort(ages.begin(), ages.end()); for (int i = n - 1; i >= 1; --i) { for (int j = i - 1; j >= 0; --j) { if (ages[j] <= 0.5 * ages[i] + 7) continue; if (ages[i] == ages[j]) ++res; ++res; } } return res; } };
咱們能夠來優化一下上面的解法,根據上面的分析,其實題目給的這三個條件能夠概括成一個條件,若A想加B的好友,那麼B的年齡必須在 (A*0.5+7, A] 這個範圍內,因爲區間要有意義的話,A*0.5+7 < A 必須成立,解出 A > 14,那麼A最小就只能取15了。意思說你不能加小於15歲的好友(青少年成長保護???)。咱們的優化思路是對於每個年齡,咱們都只要求出上面那個區間範圍內的個數,就是符合題意的。那麼既然是求區域和,創建累加數組就是一個很好的選擇了,首先咱們先創建一個統計數組numInAge,範圍是[0, 120],用來統計在各個年齡點上有多少人,而後再創建累加和數組sumInAge。這個都創建好了之後,咱們就能夠開始遍歷,因爲以前說了不能加小於15的好友,因此咱們從15開始遍歷,若是某個年齡點沒有人,直接跳過。而後就是統計出 (A*0.5+7, A] 這個範圍內有多少人,能夠經過累計和數組來快速求的,因爲當前時間點的人能夠跟這個區間內的全部發好友申請,而當前時間點可能還有多人,因此兩者相乘,但因爲咱們但區間裏還包括但當前年齡點自己,因此還要減去當前年齡點上的人數,參見代碼以下:
解法二:
class Solution { public: int numFriendRequests(vector<int>& ages) { int res = 0; vector<int> numInAge(121), sumInAge(121); for (int age : ages) ++numInAge[age]; for (int i = 1; i <= 120; ++i) { sumInAge[i] = numInAge[i] + sumInAge[i - 1]; } for (int i = 15; i <= 120; ++i) { if (numInAge[i] == 0) continue; int cnt = sumInAge[i] - sumInAge[i * 0.5 + 7]; res += cnt * numInAge[i] - numInAge[i]; } return res; } };
參考資料:
https://leetcode.com/problems/friends-of-appropriate-ages/