You are given an integer n indicating the number of people in a network. Each person is labeled from 0 to n - 1.
You are also given a 0-indexed 2D integer array restrictions, where restrictions[i] = [xi, yi] means that person xi and person yi cannot become friends, either directly or indirectly through other people.
Initially, no one is friends with each other. You are given a list of friend requests as a 0-indexed 2D integer array requests, where requests[j] = [uj, vj] is a friend request between person uj and person vj.
A friend request is successful if uj and vj can be friends. Each friend request is processed in the given order (i.e., requests[j] occurs before requests[j + 1]), and upon a successful request, uj and vj become direct friends for all future friend requests.
Return a boolean array result, where each result[j] is true if the jth friend request is successful or false if it is not.
Note: If uj and vj are already direct friends, the request is still successful.
Example 1:
Input: n = 3, restrictions = [[0,1]], requests = [[0,2],[2,1]] Output: [true,false] Explanation: Request 0: Person 0 and person 2 can be friends, so they become direct friends. Request 1: Person 2 and person 1 cannot be friends since person 0 and person 1 would be indirect friends (1--2--0).
Example 2:
Input: n = 3, restrictions = [[0,1]], requests = [[1,2],[0,2]] Output: [true,false] Explanation: Request 0: Person 1 and person 2 can be friends, so they become direct friends. Request 1: Person 0 and person 2 cannot be friends since person 0 and person 1 would be indirect friends (0--2--1).
Example 3:
Input: n = 5, restrictions = [[0,1],[1,2],[2,3]], requests = [[0,4],[1,2],[3,1],[3,4]] Output: [true,false,true,false] Explanation: Request 0: Person 0 and person 4 can be friends, so they become direct friends. Request 1: Person 1 and person 2 cannot be friends since they are directly restricted. Request 2: Person 3 and person 1 can be friends, so they become direct friends. Request 3: Person 3 and person 4 cannot be friends since person 0 and person 1 would be indirect friends (0--4--3--1).
Constraints:
2 <= n <= 10000 <= restrictions.length <= 1000restrictions[i].length == 20 <= xi, yi <= n - 1xi != yi1 <= requests.length <= 1000requests[j].length == 20 <= uj, vj <= n - 1uj != vjWhen you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to processing friend requests involves checking each request individually to see if it violates any restrictions. If a request is allowed, it's processed. This continues until all requests have been examined.
Here's how the algorithm would work step-by-step:
def process_restricted_friend_requests(number_of_people, friend_requests, restrictions):
are_friends = [False] * number_of_people
friendships = set()
result = []
for request in friend_requests:
person_a, person_b = request
violates_restriction = False
# Check if the current friend request violates any restrictions
for restriction in restrictions:
blocker, person_x, person_y = restriction
if (person_a == person_x and person_b == person_y) or \
(person_a == person_y and person_b == person_x):
if are_friends[blocker]:
violates_restriction = True
break
if violates_restriction:
result.append(False)
else:
# Only add as friends if no restrictions are violated
friendships.add(tuple(sorted((person_a, person_b))))
are_friends[person_a] = True
are_friends[person_b] = True
result.append(True)
return resultWe need to process friend requests while respecting some restrictions, meaning certain friendships are not allowed. The efficient way is to check for conflicts *before* establishing a friendship, and only proceed if it's safe. This way, we avoid unnecessary steps and potential problems.
Here's how the algorithm would work step-by-step:
def process_friend_requests(number_of_users, requests, restrictions):
friendships = [[] for _ in range(number_of_users)]
results = []
for request in requests:
user_id_1, user_id_2 = request[0], request[1]
violation_found = False
# Check if adding the friendship violates restrictions
for restriction in restrictions:
restricted_user_1, restricted_user_2 = restriction[0], restriction[1]
if (user_id_1 == restricted_user_1 and user_id_2 == restricted_user_2) or \
(user_id_1 == restricted_user_2 and user_id_2 == restricted_user_1):
violation_found = True
break
if violation_found:
results.append(False)
else:
# Only add friendship if no restriction is violated
friendships[user_id_1].append(user_id_2)
friendships[user_id_2].append(user_id_1)
results.append(True)
return results| Case | How to Handle |
|---|---|
| Empty friends list or no restrictions provided | If the friends list or the restrictions list is empty, all requests can be processed, so return a list of True values with the same length as the friend requests. |
| Friends and restrictions list have different lengths | Raise an error or return a specific error code because this indicates invalid input. |
| Cyclic restrictions exist (A restricts B, B restricts C, C restricts A) | Use a proper graph algorithm to check for cycles in the restriction graph to avoid infinite loops during processing. |
| Large number of friends and requests causing potential memory issues | Consider using generators or iterative approaches instead of recursion to reduce memory consumption for very large inputs. |
| Friend indices are out of bounds for the number of friends | Check if friend indices are within the valid range (0 to N-1, where N is the number of friends) and return False or throw an exception if invalid. |
| Restriction indices are out of bounds for the number of friends | Check restriction indices are within the valid range and return False or throw an exception if invalid. |
| Conflicting restrictions regarding the same pair of friends | Handle these conflicts by either prioritizing one restriction over another (e.g., based on order in the input list) or by flagging these requests as invalid. |
| Extremely large number of requests causing performance bottleneck | Optimize the restriction checking process using data structures like hash maps or sets to achieve faster lookups and improve the overall performance. |