Talentd
FleetCode
Make and follow sheets.Sign in

Friends Of Appropriate Ages solution and explanation

MediumArrayBinary SearchSortingTwo Pointers6 min read49.9% acceptanceUpdated 9 Apr 2026
Leetcode 825 Friends Of Appropriate AgesRen Zhang · 10:39 · 5K viewsWatch on YouTube
9 more videos on this problem
  1. Leetcode 825 Friends Of Appropriate AgesRen Zhang · 10:39 · 5K views
  2. Facebook Coding Interview Question | Leetcode 825 | Friends Of Appropriate AgesWorkWithGoogler · 15:52 · 3K views
  3. 825. Friends Of Appropriate Ages (Leetcode Medium)Programming Live with Larry · 14:53 · 1K views
  4. Leetcode 825(medium). Friends of Appropriate Ages【Array】中文AndroidBabies安卓大宝贝们 · 21:16 · 715 views
  5. LeetCode 825. Friends Of Appropriate Ages | JSer - JavaScript & AlgorithmJSer · 34:01 · 605 views
  6. 小旭讲解 LeetCode 825. Friends Of Appropriate Ages - EP29HU Xiaoxu · 13:44 · 588 views
  7. 825. Friends Of Appropriate AgesJust Coding, with Jie · 13:04 · 572 views
  8. Friends Of Appropriate Ages || Coder Army || Lec :- 9Byte Benders · 13:54 · 516 views
  9. Friends Of Appropriate AgesOwen Wu · 1:57 · 509 views
  10. LEETCODE 825. Friends Of Appropriate Ages (中文 | Java)和歌山小喵 · 2:37 · 369 views

The problem

There are n persons on a social media website. You are given an integer array ages where ages[i] is the age of the ith person.

A Person x will not send a friend request to a person y (x != y) if any of the following conditions is true:

  • age[y] <= 0.5 * age[x] + 7
  • age[y] > age[x]
  • age[y] > 100 && age[x] < 100

Otherwise, x will send a friend request to y.

Note that if x sends a request to y, y will not necessarily send a request to x. Also, a person will not send a friend request to themself.

Return the total number of friend requests made.

Example 1:

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

Example 2:

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

Example 3:

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

Constraints:

  • n == ages.length
  • 1 <= n <= 2 * 104
  • 1 <= ages[i] <= 120

Approach overview

Problem Overview: You receive an array where ages[i] represents a person's age. A person A can send a friend request to B only if specific age constraints are satisfied. The task is to count how many valid friend requests are sent across the entire group. The challenge is avoiding unnecessary pair checks when the input size grows.

Approach 1: Brute Force Pair Checking (Time: O(n2), Space: O(1))

Iterate through every pair of people using two nested loops. For each pair (i, j), verify the three rules: age[j] > 0.5 * age[i] + 7, age[j] <= age[i], and the special constraint involving ages above 100. If the conditions pass, count the request. This approach directly models the problem logic and is easy to implement, but it performs a comparison for every pair. With up to thousands of people, the O(n²) time complexity becomes expensive. It works well only for small inputs or when validating the rules during initial problem exploration using basic array traversal.

Approach 2: Optimized Counting with Age Frequency (Time: O(n + A2), Space: O(A))

Instead of checking every pair of individuals, count how many people have each age. Since ages range only from 1 to 120, build a frequency array where count[a] stores how many people are age a. Then iterate over all age pairs (ageA, ageB). If the friend request rules allow someone of age ageA to send a request to ageB, add count[ageA] * count[ageB] to the result. When ageA == ageB, subtract self-requests because a person cannot send a request to themselves.

This optimization dramatically reduces work because you evaluate at most 120 × 120 age combinations instead of n² people combinations. The idea relies on grouping values and applying conditions to aggregated counts. You can also improve the constant factor by sorting the ages and using two pointers or binary search to locate valid ranges for each age. All these variants rely on the same insight: friend requests depend only on age ranges, not individual identities.

Recommended for interviews: Interviewers expect you to move beyond the brute force check quickly. Starting with the O(n²) approach shows you understand the request rules. The optimized counting or sorted two-pointer method demonstrates algorithmic thinking and reduces the complexity to roughly O(n + A²) (with A = 120) or near-linear time after sorting. That improvement is the key signal of strong problem-solving skill.

Approach 1: Brute Force Approach

In this approach, we will use two nested loops to check all possible pairs of people. For each pair, we will check the conditions provided in the problem to determine if a friend request should be sent. Though simple, this approach can be inefficient for larger datasets.

class Solution:
    def numFriendRequests(self, ages):
        count = 0
        for i in range(len(ages)):
            for j in range(len(ages)):
                if i != j:
                    if not (ages[j] <= 0.5 * ages[i] + 7 or ages[j] > ages[i] or (ages[j] > 100 and ages[i] < 100)):
                        count += 1
        return count

# Example Usage
sol = Solution()
print(sol.numFriendRequests([16, 16]))  # Output: 2
print(sol.numFriendRequests([16, 17, 18]))  # Output: 2
print(sol.numFriendRequests([20, 30, 100, 110, 120]))  # Output: 3
import java.util.List;

public class Solution {
    public int numFriendRequests(int[] ages) {
        int count = 0;
        for (int i = 0; i < ages.length; i++) {
            for (int j = 0; j < ages.length; j++) {
                if (i != j) {
                    if (!(ages[j] <= 0.5 * ages[i] + 7 || ages[j] > ages[i] || (ages[j] > 100 && ages[i] < 100))) {
                        count++;
                    }
                }
            }
        }
        return count;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        int[] ages1 = {16, 16};
        System.out.println(sol.numFriendRequests(ages1)); // Output: 2
        int[] ages2 = {16, 17, 18};
        System.out.println(sol.numFriendRequests(ages2)); // Output: 2
        int[] ages3 = {20, 30, 100, 110, 120};
        System.out.println(sol.numFriendRequests(ages3)); // Output: 3
    }
}
#include <vector>
using namespace std;

class Solution {
public:
    int numFriendRequests(vector<int>& ages) {
        int count = 0;
        for (int i = 0; i < ages.size(); ++i) {
            for (int j = 0; j < ages.size(); ++j) {
                if (i != j) {
                    if (!(ages[j] <= 0.5 * ages[i] + 7 || ages[j] > ages[i] || (ages[j] > 100 && ages[i] < 100))) {
                        count++;
                    }
                }
            }
        }
        return count;
    }
};

int main() {
    Solution sol;
    vector<int> ages1 = {16, 16};
    printf("%d\n", sol.numFriendRequests(ages1)); // Output: 2
    vector<int> ages2 = {16, 17, 18};
    printf("%d\n", sol.numFriendRequests(ages2)); // Output: 2
    vector<int> ages3 = {20, 30, 100, 110, 120};
    printf("%d\n", sol.numFriendRequests(ages3)); // Output: 3
    return 0;
}
function numFriendRequests(ages) {
    let count = 0;
    for (let i = 0; i < ages.length; i++) {
        for (let j = 0; j < ages.length; j++) {
            if (i !== j) {
                if (!(ages[j] <= 0.5 * ages[i] + 7 || ages[j] > ages[i] || (ages[j] > 100 && ages[i] < 100))) {
                    count++;
                }
            }
        }
    }
    return count;
}

console.log(numFriendRequests([16, 16])); // Output: 2
console.log(numFriendRequests([16, 17, 18])); // Output: 2
console.log(numFriendRequests([20, 30, 100, 110, 120])); // Output: 3
#include <stdio.h>

int numFriendRequests(int* ages, int agesSize) {
    int count = 0;
    for (int i = 0; i < agesSize; i++) {
        for (int j = 0; j < agesSize; j++) {
            if (i != j) {
                if (!(ages[j] <= 0.5 * ages[i] + 7 || ages[j] > ages[i] || (ages[j] > 100 && ages[i] < 100))) {
                    count++;
                }
            }
        }
    }
    return count;
}

int main() {
    int ages1[] = {16, 16};
    printf("%d\n", numFriendRequests(ages1, 2)); // Output: 2

    int ages2[] = {16, 17, 18};
    printf("%d\n", numFriendRequests(ages2, 3)); // Output: 2

    int ages3[] = {20, 30, 100, 110, 120};
    printf("%d\n", numFriendRequests(ages3, 5)); // Output: 3

    return 0;
}
public class Solution {
    public int NumFriendRequests(int[] ages) {
        int count = 0;
        for (int i = 0; i < ages.Length; i++) {
            for (int j = 0; j < ages.Length; j++) {
                if (i != j && !(ages[j] <= 0.5 * ages[i] + 7 || ages[j] > ages[i] || (ages[j] > 100 && ages[i] < 100))) {
                    count++;
                }
            }
        }
        return count;
    }

    public static void Main(string[] args) {
        Solution sol = new Solution();
        Console.WriteLine(sol.NumFriendRequests(new int[] { 16, 16 })); // Output: 2
        Console.WriteLine(sol.NumFriendRequests(new int[] { 16, 17, 18 })); // Output: 2
        Console.WriteLine(sol.NumFriendRequests(new int[] { 20, 30, 100, 110, 120 })); // Output: 3
    }
}

The Python solution uses two nested loops, iterating through all combinations of pairs and applying the relevant conditions for valid friend requests.

Complexity

Time Complexity: O(n^2)
Space Complexity: O(1)

Try this approach in the editor

Approach 2: Optimized Counting Approach

To optimize the previous brute force solution, we can use counting to reduce the number of comparisons. By first counting the occurrences of each age, we minimize unnecessary comparisons through sorted age analysis.

class Solution:
    def numFriendRequests(self, ages):
        from collections import Counter
        count = Counter(ages)
        requests = 0
        for ageA in count:
            for ageB in count:
                if not (ageB <= 0.5 * ageA + 7 or ageB > ageA or (ageB > 100 and ageA < 100)):
                    if ageA == ageB:
                        requests += count[ageA] * (count[ageB] - 1)
                    else:
                        requests += count[ageA] * count[ageB]
        return requests

# Example Usage
sol = Solution()
print(sol.numFriendRequests([16, 16]))  # Output: 2
print(sol.numFriendRequests([16, 17, 18]))  # Output: 2
print(sol.numFriendRequests([20, 30, 100, 110, 120]))  # Output: 3
import java.util.Arrays;

public class Solution {
    public int numFriendRequests(int[] ages) {
        int[] count = new int[121];
        for (int age : ages) {
            count[age]++;
        }

        int requests = 0;
        for (int ageA = 0; ageA < 121; ageA++) {
            for (int ageB = 0; ageB < 121; ageB++) {
                if (count[ageA] > 0 && count[ageB] > 0) {
                    if (!(ageB <= 0.5 * ageA + 7 || ageB > ageA || (ageB > 100 && ageB > 100 && ageA < 100))) {
                        requests += count[ageA] * (count[ageB] - (ageA == ageB ? 1 : 0));
                    }
                }
            }
        }
        return requests;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        System.out.println(sol.numFriendRequests(new int[] {16, 16})); // Output: 2
        System.out.println(sol.numFriendRequests(new int[] {16, 17, 18})); // Output: 2
        System.out.println(sol.numFriendRequests(new int[] {20, 30, 100, 110, 120})); // Output: 3
    }
}
#include <vector>
using namespace std;
#define MAX_AGE 121

class Solution {
public:
    int numFriendRequests(vector<int>& ages) {
        vector<int> count(MAX_AGE, 0);
        for (int age : ages) {
            count[age]++;
        }

        int requests = 0;
        for (int ageA = 0; ageA < MAX_AGE; ageA++) {
            for (int ageB = 0; ageB < MAX_AGE; ageB++) {
                if (count[ageA] > 0 && count[ageB] > 0) {
                    if (!(ageB <= 0.5 * ageA + 7 || ageB > ageA || (ageB > 100 && ageA < 100))) {
                        requests += count[ageA] * (count[ageB] - (ageA == ageB));
                    }
                }
            }
        }
        return requests;
    }
};

int main() {
    Solution sol;
    vector<int> ages1 = {16, 16};
    printf("%d\n", sol.numFriendRequests(ages1)); // Output: 2
    vector<int> ages2 = {16, 17, 18};
    printf("%d\n", sol.numFriendRequests(ages2)); // Output: 2
    vector<int> ages3 = {20, 30, 100, 110, 120};
    printf("%d\n", sol.numFriendRequests(ages3)); // Output: 3
    return 0;
}
function numFriendRequests(ages) {
    const MAX_AGE = 121;
    const count = new Array(MAX_AGE).fill(0);
    ages.forEach(age => count[age]++);

    let requests = 0;
    for (let ageA = 0; ageA < MAX_AGE; ageA++) {
        for (let ageB = 0; ageB < MAX_AGE; ageB++) {
            if (count[ageA] > 0 && count[ageB] > 0) {
                if (!(ageB <= 0.5 * ageA + 7 || ageB > ageA || (ageB > 100 && ageA < 100))) {
                    requests += count[ageA] * (count[ageB] - (ageA === ageB ? 1 : 0));
                }
            }
        }
    }
    return requests;
}

console.log(numFriendRequests([16, 16])); // Output: 2
console.log(numFriendRequests([16, 17, 18])); // Output: 2
console.log(numFriendRequests([20, 30, 100, 110, 120])); // Output: 3
#include <stdio.h>
#include <memory.h>

define MAX_AGE 121

int numFriendRequests(int* ages, int agesSize) {
    int count[MAX_AGE] = {0};
    for (int i = 0; i < agesSize; i++) {
        count[ages[i]]++;
    }

    int requests = 0;
    for (int ageA = 0; ageA < MAX_AGE; ageA++) {
        for (int ageB = 0; ageB < MAX_AGE; ageB++) {
            if (count[ageA] > 0 && count[ageB] > 0) {
                if (!(ageB <= 0.5 * ageA + 7 || ageB > ageA || (ageB > 100 && ageA < 100))) {
                    requests += count[ageA] * (count[ageB] - (ageA == ageB));
                }
            }
        }
    }
    return requests;
}

int main() {
    int ages1[] = {16, 16};
    printf("%d\n", numFriendRequests(ages1, 2)); // Output: 2

    int ages2[] = {16, 17, 18};
    printf("%d\n", numFriendRequests(ages2, 3)); // Output: 2

    int ages3[] = {20, 30, 100, 110, 120};
    printf("%d\n", numFriendRequests(ages3, 5)); // Output: 3

    return 0;
}
using System;

public class Solution {
    public int NumFriendRequests(int[] ages) {
        int[] count = new int[121];
        foreach (int age in ages) {
            count[age]++;
        }

        int requests = 0;
        for (int ageA = 0; ageA < 121; ageA++) {
            for (int ageB = 0; ageB < 121; ageB++) {
                if (count[ageA] > 0 && count[ageB] > 0) {
                    if (!(ageB <= 0.5 * ageA + 7 || ageB > ageA || (ageB > 100 && ageA < 100))) {
                        requests += count[ageA] * (count[ageB] - (ageA == ageB ? 1 : 0));
                    }
                }
            }
        }
        return requests;
    }

    public static void Main() {
        Solution sol = new Solution();
        Console.WriteLine(sol.NumFriendRequests(new int[] { 16, 16 })); // Output: 2
        Console.WriteLine(sol.NumFriendRequests(new int[] { 16, 17, 18 })); // Output: 2
        Console.WriteLine(sol.NumFriendRequests(new int[] { 20, 30, 100, 110, 120 })); // Output: 3
    }
}

Using Python's collections framework, we keep track of each age's frequency, minimizing pairwise comparisons, leading to an efficient solution.

Complexity

Time Complexity: O(MAX_AGE^2) = O(121^2)
Space Complexity: O(MAX_AGE) = O(121)

Try this approach in the editor

Approach 3: Counting + Enumeration

We can use an array cnt of length 121 to record the number of people of each age.

Next, we enumerate all possible age pairs (ax, ay). If ax and ay satisfy the conditions given in the problem, these age pairs (ax, ay) can send friend requests to each other.

If ax = ay, meaning the ages are the same, then the number of friend requests between ax and ay is cnt[ax] times (cnt[ax] - 1). Otherwise, if the ages are different, the number of friend requests between ax and ay is cnt[ax] times cnt[ay]. We accumulate these friend request counts into the answer.

The time complexity is O(n + m^2), where n is the length of the array ages, and m is the maximum age, which is 121 in this problem.

function numFriendRequests(ages: number[]): number {
    const m = 121;
    const cnt = Array(m).fill(0);
    for (const x of ages) {
        cnt[x]++;
    }

    let ans = 0;
    for (let ax = 0; ax < m; ax++) {
        for (let ay = 0; ay < m; ay++) {
            if (ay <= 0.5 * ax + 7 || ay > ax || (ay > 100 && ax < 100)) {
                continue;
            }
            ans += cnt[ax] * (cnt[ay] - (ax === ay ? 1 : 0));
        }
    }

    return ans;
}
func numFriendRequests(ages []int) (ans int) {
	cnt := [121]int{}
	for _, x := range ages {
		cnt[x]++
	}
	for ax, x := range cnt {
		for ay, y := range cnt {
			if ay <= ax/2+7 || ay > ax || (ay > 100 && ax < 100) {
				continue
			}
			if ax == ay {
				ans += x * (x - 1)
			} else {
				ans += x * y
			}
		}
	}

	return
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Brute Force Approach

Time Complexity: O(n^2)
Space Complexity: O(1)

Optimized Counting Approach

Time Complexity: O(MAX_AGE^2) = O(121^2)
Space Complexity: O(MAX_AGE) = O(121)

Counting + Enumeration–

Complexity analysis

ApproachTimeSpaceWhen to Use
Brute Force Pair CheckO(n²)O(1)Good for understanding the request rules or when input size is very small
Sorting + Two PointersO(n log n)O(1)Useful when working directly on the sorted ages array and finding valid ranges efficiently
Counting by Age Frequency (Optimal)O(n + A²)O(A)Best when ages are within a small fixed range (1–120), allowing aggregated counting

Frequently asked questions

Is Friends Of Appropriate Ages easy or hard?

Friends Of Appropriate Ages is rated Medium difficulty. The rules for valid requests are straightforward, but the challenge is recognizing that checking every pair is inefficient. Efficient solutions rely on sorting, two pointers, or counting techniques.

Friends Of Appropriate Ages Python/Java solution

Python and Java implementations typically follow the same idea: either sort the ages and use two pointers to find valid ranges, or build a frequency array of size 121 and compute valid age combinations. Both approaches significantly reduce unnecessary pair comparisons.

How to solve Friends Of Appropriate Ages in O(n)?

A near-linear solution uses an age frequency array and prefix counts. Instead of evaluating each person pair, count how many people exist for each age and compute valid ranges that satisfy the request rules. Because the age range is limited to 120 values, the computation effectively behaves like O(n).

What is the best approach for Friends Of Appropriate Ages?

The most efficient approach counts how many people have each age and evaluates valid age pairs instead of individual pairs. Since ages range from 1 to 120, you can iterate through all age combinations and apply the friend request rules. This reduces the complexity to roughly O(n + A^2) where A is the age range (120), making it far faster than O(n^2).

Is Friends Of Appropriate Ages asked at Google/Amazon/Meta?

Friends Of Appropriate Ages appears in interview preparation sets for companies such as Amazon, Google, and Meta because it tests reasoning with constraints, counting optimizations, and range-based conditions. The problem also evaluates your ability to move from brute force to aggregated counting or two-pointer techniques.

What data structure is used in Friends Of Appropriate Ages?

The common solutions use arrays for age storage and a frequency array for counting how many people share the same age. Some implementations also use sorting combined with two pointers or binary search to find valid age ranges efficiently.

What is the time complexity of Friends Of Appropriate Ages?

The brute force solution runs in O(n^2) because every pair of people must be checked. The optimized counting approach runs in O(n + A^2), where A is the maximum possible age (120). Sorting-based solutions run in O(n log n) followed by linear scans with two pointers.

Comments

Now write it yourselfClose this page and solve Friends Of Appropriate Ages in the editor, without looking.
Practise Friends Of Appropriate Ages