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, 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.
The key insight is using Union-Find to efficiently track connected components while validating that merging components won't violate any restrictions. The optimal approach simulates the union operation to check all restriction pairs before actually performing the merge. Time: O(m × (n + r × α(n))), Space: O(n)
Common Approaches
Approach
Time
Space
Notes
✓
Brute Force with DFS
O(m × (n + e))
O(n + e)
Use DFS to check if two people are already connected before each request
Union-Find with Restriction Validation
O(m × (n + r × α(n)))
O(n)
Use Union-Find to efficiently track connected components and validate restrictions
Brute Force with DFS — Algorithm Steps
Step 1: For each request, use DFS to find all friends of person u
Step 2: Check if person v is already connected to u
Step 3: Check if connecting u and v would violate any restrictions
Step 4: If valid, add the connection to adjacency list
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Request Processing
Process each friend request in order
2
DFS Search
Use DFS to find if two people are connected
3
Restriction Check
Verify new connection doesn't violate restrictions
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_N 1000
#define MAX_REQUESTS 1000
typedef struct {
int adj[MAX_N][MAX_N];
int degree[MAX_N];
} Graph;
bool dfs(Graph* g, int start, int target, bool* visited, int n) {
if (start == target) return true;
visited[start] = true;
for (int i = 0; i < g->degree[start]; i++) {
int neighbor = g->adj[start][i];
if (!visited[neighbor]) {
if (dfs(g, neighbor, target, visited, n)) {
return true;
}
}
}
return false;
}
void getComponent(Graph* g, int node, bool* component, int n) {
bool visited[MAX_N] = {false};
int stack[MAX_N];
int top = 0;
stack[top++] = node;
while (top > 0) {
int curr = stack[--top];
if (!visited[curr]) {
visited[curr] = true;
component[curr] = true;
for (int i = 0; i < g->degree[curr]; i++) {
int neighbor = g->adj[curr][i];
if (!visited[neighbor]) {
stack[top++] = neighbor;
}
}
}
}
}
void addEdge(Graph* g, int u, int v) {
g->adj[u][g->degree[u]++] = v;
g->adj[v][g->degree[v]++] = u;
}
bool* solution(int n, int restrictionsSize, int** restrictions, int* restrictionsColSize, int requestsSize, int** requests, int* requestsColSize, int* returnSize) {
Graph g;
memset(&g, 0, sizeof(g));
bool* result = (bool*)malloc(requestsSize * sizeof(bool));
*returnSize = requestsSize;
for (int i = 0; i < requestsSize; i++) {
int u = requests[i][0];
int v = requests[i][1];
bool visited[MAX_N] = {false};
if (u == v || dfs(&g, u, v, visited, n)) {
result[i] = true;
continue;
}
bool compU[MAX_N] = {false};
bool compV[MAX_N] = {false};
getComponent(&g, u, compU, n);
getComponent(&g, v, compV, n);
bool valid = true;
for (int j = 0; j < restrictionsSize; j++) {
int x = restrictions[j][0];
int y = restrictions[j][1];
if ((compU[x] && compV[y]) || (compU[y] && compV[x])) {
valid = false;
break;
}
}
if (valid) {
addEdge(&g, u, v);
result[i] = true;
} else {
result[i] = false;
}
}
return result;
}
int main() {
int n;
scanf("%d", &n);
// Parse restrictions
char line[10000];
fgets(line, sizeof(line), stdin); // consume newline
fgets(line, sizeof(line), stdin);
// Simple parsing for restrictions
int restrictionsSize = 0;
int** restrictions = NULL;
int* restrictionsColSize = NULL;
// Parse requests
fgets(line, sizeof(line), stdin);
int requestsSize = 0;
int** requests = NULL;
int* requestsColSize = NULL;
// For demonstration, using sample data
restrictionsSize = 1;
restrictions = (int**)malloc(restrictionsSize * sizeof(int*));
restrictionsColSize = (int*)malloc(restrictionsSize * sizeof(int));
restrictions[0] = (int*)malloc(2 * sizeof(int));
restrictions[0][0] = 0; restrictions[0][1] = 1;
restrictionsColSize[0] = 2;
requestsSize = 3;
requests = (int**)malloc(requestsSize * sizeof(int*));
requestsColSize = (int*)malloc(requestsSize * sizeof(int));
for (int i = 0; i < requestsSize; i++) {
requests[i] = (int*)malloc(2 * sizeof(int));
requestsColSize[i] = 2;
}
requests[0][0] = 1; requests[0][1] = 2;
requests[1][0] = 0; requests[1][1] = 2;
requests[2][0] = 0; requests[2][1] = 1;
int returnSize;
bool* result = solution(n, restrictionsSize, restrictions, restrictionsColSize, requestsSize, requests, requestsColSize, &returnSize);
printf("[");
for (int i = 0; i < returnSize; i++) {
printf("%s", result[i] ? "true" : "false");
if (i < returnSize - 1) printf(",");
}
printf("]\n");
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(m × (n + e))
For each of m requests, we do DFS which takes O(n + e) where e is current edges
n
2n
✓ Linear Growth
Space Complexity
O(n + e)
Adjacency list stores all edges and DFS uses recursion stack
n
2n
⚡ Linearithmic Space
28.5K Views
MediumFrequency
~35 minAvg. Time
427 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.