Skip to content

Commit 68b4860

Browse files
authoredApr 17, 2024··
feat: add solutions to lc problem: No.2076 (#2606)
1 parent a32a03a commit 68b4860

File tree

7 files changed

+313
-214
lines changed

7 files changed

+313
-214
lines changed
 

‎solution/2000-2099/2076.Process Restricted Friend Requests/README.md

+107-71
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@
7272

7373
## 解法
7474

75-
### 方法一
75+
### 方法一:并查集
76+
77+
我们可以用并查集来维护朋友关系,然后对于每个请求,判断是否满足限制条件。
78+
79+
对于当前请求的两个人 $(u, v)$,如果他们已经是朋友,那么可以直接接受请求;否则,我们遍历限制条件,如果存在限制条件 $(x, y)$,使得 $u$ 和 $x$ 互为朋友并且 $v$ 和 $y$ 互为朋友,或者 $u$ 和 $y$ 互为朋友并且 $v$ 和 $x$ 互为朋友,那么就不能接受请求。
80+
81+
时间复杂度 $O(q \times m \times \log(n))$,空间复杂度 $O(n)$。其中 $q$ 和 $m$ 分别是请求的数量和限制条件的数量。
7682

7783
<!-- tabs:start -->
7884

@@ -81,29 +87,27 @@ class Solution:
8187
def friendRequests(
8288
self, n: int, restrictions: List[List[int]], requests: List[List[int]]
8389
) -> List[bool]:
84-
p = list(range(n))
85-
86-
def find(x):
90+
def find(x: int) -> int:
8791
if p[x] != x:
8892
p[x] = find(p[x])
8993
return p[x]
9094

95+
p = list(range(n))
9196
ans = []
92-
i = 0
9397
for u, v in requests:
94-
if find(u) == find(v):
98+
pu, pv = find(u), find(v)
99+
if pu == pv:
95100
ans.append(True)
96101
else:
97-
valid = True
102+
ok = True
98103
for x, y in restrictions:
99-
if (find(u) == find(x) and find(v) == find(y)) or (
100-
find(u) == find(y) and find(v) == find(x)
101-
):
102-
valid = False
104+
px, py = find(x), find(y)
105+
if (pu == px and pv == py) or (pu == py and pv == px):
106+
ok = False
103107
break
104-
ans.append(valid)
105-
if valid:
106-
p[find(u)] = find(v)
108+
ans.append(ok)
109+
if ok:
110+
p[pu] = pv
107111
return ans
108112
```
109113

@@ -116,27 +120,25 @@ class Solution {
116120
for (int i = 0; i < n; ++i) {
117121
p[i] = i;
118122
}
119-
boolean[] ans = new boolean[requests.length];
120-
int i = 0;
121-
for (int[] req : requests) {
122-
int u = req[0], v = req[1];
123-
if (find(u) == find(v)) {
124-
ans[i++] = true;
123+
int m = requests.length;
124+
boolean[] ans = new boolean[m];
125+
for (int i = 0; i < m; ++i) {
126+
int u = requests[i][0], v = requests[i][1];
127+
int pu = find(u), pv = find(v);
128+
if (pu == pv) {
129+
ans[i] = true;
125130
} else {
126-
boolean valid = true;
127-
for (int[] res : restrictions) {
128-
int x = res[0], y = res[1];
129-
if ((find(u) == find(x) && find(v) == find(y))
130-
|| (find(u) == find(y) && find(v) == find(x))) {
131-
valid = false;
131+
boolean ok = true;
132+
for (var r : restrictions) {
133+
int px = find(r[0]), py = find(r[1]);
134+
if ((pu == px && pv == py) || (pu == py && pv == px)) {
135+
ok = false;
132136
break;
133137
}
134138
}
135-
if (valid) {
136-
p[find(u)] = find(v);
137-
ans[i++] = true;
138-
} else {
139-
ans[i++] = false;
139+
if (ok) {
140+
ans[i] = true;
141+
p[pu] = pv;
140142
}
141143
}
142144
}
@@ -155,75 +157,109 @@ class Solution {
155157
```cpp
156158
class Solution {
157159
public:
158-
vector<int> p;
159-
160160
vector<bool> friendRequests(int n, vector<vector<int>>& restrictions, vector<vector<int>>& requests) {
161-
p.resize(n);
162-
for (int i = 0; i < n; ++i) p[i] = i;
161+
vector<int> p(n);
162+
iota(p.begin(), p.end(), 0);
163+
function<int(int)> find = [&](int x) {
164+
if (p[x] != x) {
165+
p[x] = find(p[x]);
166+
}
167+
return p[x];
168+
};
163169
vector<bool> ans;
164170
for (auto& req : requests) {
165171
int u = req[0], v = req[1];
166-
if (find(u) == find(v))
172+
int pu = find(u), pv = find(v);
173+
if (pu == pv) {
167174
ans.push_back(true);
168-
else {
169-
bool valid = true;
170-
for (auto& res : restrictions) {
171-
int x = res[0], y = res[1];
172-
if ((find(u) == find(x) && find(v) == find(y)) || (find(u) == find(y) && find(v) == find(x))) {
173-
valid = false;
175+
} else {
176+
bool ok = true;
177+
for (auto& r : restrictions) {
178+
int px = find(r[0]), py = find(r[1]);
179+
if ((pu == px && pv == py) || (pu == py && pv == px)) {
180+
ok = false;
174181
break;
175182
}
176183
}
177-
ans.push_back(valid);
178-
if (valid) p[find(u)] = find(v);
184+
ans.push_back(ok);
185+
if (ok) {
186+
p[pu] = pv;
187+
}
179188
}
180189
}
181190
return ans;
182191
}
183-
184-
int find(int x) {
185-
if (p[x] != x) p[x] = find(p[x]);
186-
return p[x];
187-
}
188192
};
189193
```
190194
191195
```go
192-
var p []int
193-
194-
func friendRequests(n int, restrictions [][]int, requests [][]int) []bool {
195-
p = make([]int, n)
196-
for i := 0; i < n; i++ {
196+
func friendRequests(n int, restrictions [][]int, requests [][]int) (ans []bool) {
197+
p := make([]int, n)
198+
for i := range p {
197199
p[i] = i
198200
}
199-
var ans []bool
201+
var find func(int) int
202+
find = func(x int) int {
203+
if p[x] != x {
204+
p[x] = find(p[x])
205+
}
206+
return p[x]
207+
}
200208
for _, req := range requests {
201-
u, v := req[0], req[1]
202-
if find(u) == find(v) {
209+
pu, pv := find(req[0]), find(req[1])
210+
if pu == pv {
203211
ans = append(ans, true)
204212
} else {
205-
valid := true
206-
for _, res := range restrictions {
207-
x, y := res[0], res[1]
208-
if (find(u) == find(x) && find(v) == find(y)) || (find(u) == find(y) && find(v) == find(x)) {
209-
valid = false
213+
ok := true
214+
for _, r := range restrictions {
215+
px, py := find(r[0]), find(r[1])
216+
if px == pu && py == pv || px == pv && py == pu {
217+
ok = false
210218
break
211219
}
212220
}
213-
ans = append(ans, valid)
214-
if valid {
215-
p[find(u)] = find(v)
221+
ans = append(ans, ok)
222+
if ok {
223+
p[pv] = pu
216224
}
217225
}
218226
}
219-
return ans
227+
return
220228
}
229+
```
221230

222-
func find(x int) int {
223-
if p[x] != x {
224-
p[x] = find(p[x])
225-
}
226-
return p[x]
231+
```ts
232+
function friendRequests(n: number, restrictions: number[][], requests: number[][]): boolean[] {
233+
const p: number[] = Array.from({ length: n }, (_, i) => i);
234+
const find = (x: number): number => {
235+
if (p[x] !== x) {
236+
p[x] = find(p[x]);
237+
}
238+
return p[x];
239+
};
240+
const ans: boolean[] = [];
241+
for (const [u, v] of requests) {
242+
const pu = find(u);
243+
const pv = find(v);
244+
if (pu === pv) {
245+
ans.push(true);
246+
} else {
247+
let ok = true;
248+
for (const [x, y] of restrictions) {
249+
const px = find(x);
250+
const py = find(y);
251+
if ((px === pu && py === pv) || (px === pv && py === pu)) {
252+
ok = false;
253+
break;
254+
}
255+
}
256+
ans.push(ok);
257+
if (ok) {
258+
p[pu] = pv;
259+
}
260+
}
261+
}
262+
return ans;
227263
}
228264
```
229265

‎solution/2000-2099/2076.Process Restricted Friend Requests/README_EN.md

+107-71
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ Request 3: Person 3 and person 4 cannot be friends since person 0 and person 1 w
6868

6969
## Solutions
7070

71-
### Solution 1
71+
### Solution 1: Union-Find
72+
73+
We can use a union-find set to maintain the friend relationships, and then for each request, we determine whether it meets the restriction conditions.
74+
75+
For the two people $(u, v)$ in the current request, if they are already friends, then the request can be directly accepted; otherwise, we traverse the restriction conditions. If there exists a restriction condition $(x, y)$ such that $u$ and $x$ are friends and $v$ and $y$ are friends, or $u$ and $y$ are friends and $v$ and $x$ are friends, then the request cannot be accepted.
76+
77+
The time complexity is $O(q \times m \times \log(n))$, and the space complexity is $O(n)$. Where $q$ and $m$ are the number of requests and the number of restriction conditions respectively.
7278

7379
<!-- tabs:start -->
7480

@@ -77,29 +83,27 @@ class Solution:
7783
def friendRequests(
7884
self, n: int, restrictions: List[List[int]], requests: List[List[int]]
7985
) -> List[bool]:
80-
p = list(range(n))
81-
82-
def find(x):
86+
def find(x: int) -> int:
8387
if p[x] != x:
8488
p[x] = find(p[x])
8589
return p[x]
8690

91+
p = list(range(n))
8792
ans = []
88-
i = 0
8993
for u, v in requests:
90-
if find(u) == find(v):
94+
pu, pv = find(u), find(v)
95+
if pu == pv:
9196
ans.append(True)
9297
else:
93-
valid = True
98+
ok = True
9499
for x, y in restrictions:
95-
if (find(u) == find(x) and find(v) == find(y)) or (
96-
find(u) == find(y) and find(v) == find(x)
97-
):
98-
valid = False
100+
px, py = find(x), find(y)
101+
if (pu == px and pv == py) or (pu == py and pv == px):
102+
ok = False
99103
break
100-
ans.append(valid)
101-
if valid:
102-
p[find(u)] = find(v)
104+
ans.append(ok)
105+
if ok:
106+
p[pu] = pv
103107
return ans
104108
```
105109

@@ -112,27 +116,25 @@ class Solution {
112116
for (int i = 0; i < n; ++i) {
113117
p[i] = i;
114118
}
115-
boolean[] ans = new boolean[requests.length];
116-
int i = 0;
117-
for (int[] req : requests) {
118-
int u = req[0], v = req[1];
119-
if (find(u) == find(v)) {
120-
ans[i++] = true;
119+
int m = requests.length;
120+
boolean[] ans = new boolean[m];
121+
for (int i = 0; i < m; ++i) {
122+
int u = requests[i][0], v = requests[i][1];
123+
int pu = find(u), pv = find(v);
124+
if (pu == pv) {
125+
ans[i] = true;
121126
} else {
122-
boolean valid = true;
123-
for (int[] res : restrictions) {
124-
int x = res[0], y = res[1];
125-
if ((find(u) == find(x) && find(v) == find(y))
126-
|| (find(u) == find(y) && find(v) == find(x))) {
127-
valid = false;
127+
boolean ok = true;
128+
for (var r : restrictions) {
129+
int px = find(r[0]), py = find(r[1]);
130+
if ((pu == px && pv == py) || (pu == py && pv == px)) {
131+
ok = false;
128132
break;
129133
}
130134
}
131-
if (valid) {
132-
p[find(u)] = find(v);
133-
ans[i++] = true;
134-
} else {
135-
ans[i++] = false;
135+
if (ok) {
136+
ans[i] = true;
137+
p[pu] = pv;
136138
}
137139
}
138140
}
@@ -151,75 +153,109 @@ class Solution {
151153
```cpp
152154
class Solution {
153155
public:
154-
vector<int> p;
155-
156156
vector<bool> friendRequests(int n, vector<vector<int>>& restrictions, vector<vector<int>>& requests) {
157-
p.resize(n);
158-
for (int i = 0; i < n; ++i) p[i] = i;
157+
vector<int> p(n);
158+
iota(p.begin(), p.end(), 0);
159+
function<int(int)> find = [&](int x) {
160+
if (p[x] != x) {
161+
p[x] = find(p[x]);
162+
}
163+
return p[x];
164+
};
159165
vector<bool> ans;
160166
for (auto& req : requests) {
161167
int u = req[0], v = req[1];
162-
if (find(u) == find(v))
168+
int pu = find(u), pv = find(v);
169+
if (pu == pv) {
163170
ans.push_back(true);
164-
else {
165-
bool valid = true;
166-
for (auto& res : restrictions) {
167-
int x = res[0], y = res[1];
168-
if ((find(u) == find(x) && find(v) == find(y)) || (find(u) == find(y) && find(v) == find(x))) {
169-
valid = false;
171+
} else {
172+
bool ok = true;
173+
for (auto& r : restrictions) {
174+
int px = find(r[0]), py = find(r[1]);
175+
if ((pu == px && pv == py) || (pu == py && pv == px)) {
176+
ok = false;
170177
break;
171178
}
172179
}
173-
ans.push_back(valid);
174-
if (valid) p[find(u)] = find(v);
180+
ans.push_back(ok);
181+
if (ok) {
182+
p[pu] = pv;
183+
}
175184
}
176185
}
177186
return ans;
178187
}
179-
180-
int find(int x) {
181-
if (p[x] != x) p[x] = find(p[x]);
182-
return p[x];
183-
}
184188
};
185189
```
186190
187191
```go
188-
var p []int
189-
190-
func friendRequests(n int, restrictions [][]int, requests [][]int) []bool {
191-
p = make([]int, n)
192-
for i := 0; i < n; i++ {
192+
func friendRequests(n int, restrictions [][]int, requests [][]int) (ans []bool) {
193+
p := make([]int, n)
194+
for i := range p {
193195
p[i] = i
194196
}
195-
var ans []bool
197+
var find func(int) int
198+
find = func(x int) int {
199+
if p[x] != x {
200+
p[x] = find(p[x])
201+
}
202+
return p[x]
203+
}
196204
for _, req := range requests {
197-
u, v := req[0], req[1]
198-
if find(u) == find(v) {
205+
pu, pv := find(req[0]), find(req[1])
206+
if pu == pv {
199207
ans = append(ans, true)
200208
} else {
201-
valid := true
202-
for _, res := range restrictions {
203-
x, y := res[0], res[1]
204-
if (find(u) == find(x) && find(v) == find(y)) || (find(u) == find(y) && find(v) == find(x)) {
205-
valid = false
209+
ok := true
210+
for _, r := range restrictions {
211+
px, py := find(r[0]), find(r[1])
212+
if px == pu && py == pv || px == pv && py == pu {
213+
ok = false
206214
break
207215
}
208216
}
209-
ans = append(ans, valid)
210-
if valid {
211-
p[find(u)] = find(v)
217+
ans = append(ans, ok)
218+
if ok {
219+
p[pv] = pu
212220
}
213221
}
214222
}
215-
return ans
223+
return
216224
}
225+
```
217226

218-
func find(x int) int {
219-
if p[x] != x {
220-
p[x] = find(p[x])
221-
}
222-
return p[x]
227+
```ts
228+
function friendRequests(n: number, restrictions: number[][], requests: number[][]): boolean[] {
229+
const p: number[] = Array.from({ length: n }, (_, i) => i);
230+
const find = (x: number): number => {
231+
if (p[x] !== x) {
232+
p[x] = find(p[x]);
233+
}
234+
return p[x];
235+
};
236+
const ans: boolean[] = [];
237+
for (const [u, v] of requests) {
238+
const pu = find(u);
239+
const pv = find(v);
240+
if (pu === pv) {
241+
ans.push(true);
242+
} else {
243+
let ok = true;
244+
for (const [x, y] of restrictions) {
245+
const px = find(x);
246+
const py = find(y);
247+
if ((px === pu && py === pv) || (px === pv && py === pu)) {
248+
ok = false;
249+
break;
250+
}
251+
}
252+
ans.push(ok);
253+
if (ok) {
254+
p[pu] = pv;
255+
}
256+
}
257+
}
258+
return ans;
223259
}
224260
```
225261

Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
class Solution {
22
public:
3-
vector<int> p;
4-
53
vector<bool> friendRequests(int n, vector<vector<int>>& restrictions, vector<vector<int>>& requests) {
6-
p.resize(n);
7-
for (int i = 0; i < n; ++i) p[i] = i;
4+
vector<int> p(n);
5+
iota(p.begin(), p.end(), 0);
6+
function<int(int)> find = [&](int x) {
7+
if (p[x] != x) {
8+
p[x] = find(p[x]);
9+
}
10+
return p[x];
11+
};
812
vector<bool> ans;
913
for (auto& req : requests) {
1014
int u = req[0], v = req[1];
11-
if (find(u) == find(v))
15+
int pu = find(u), pv = find(v);
16+
if (pu == pv) {
1217
ans.push_back(true);
13-
else {
14-
bool valid = true;
15-
for (auto& res : restrictions) {
16-
int x = res[0], y = res[1];
17-
if ((find(u) == find(x) && find(v) == find(y)) || (find(u) == find(y) && find(v) == find(x))) {
18-
valid = false;
18+
} else {
19+
bool ok = true;
20+
for (auto& r : restrictions) {
21+
int px = find(r[0]), py = find(r[1]);
22+
if ((pu == px && pv == py) || (pu == py && pv == px)) {
23+
ok = false;
1924
break;
2025
}
2126
}
22-
ans.push_back(valid);
23-
if (valid) p[find(u)] = find(v);
27+
ans.push_back(ok);
28+
if (ok) {
29+
p[pu] = pv;
30+
}
2431
}
2532
}
2633
return ans;
2734
}
28-
29-
int find(int x) {
30-
if (p[x] != x) p[x] = find(p[x]);
31-
return p[x];
32-
}
3335
};
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
1-
var p []int
2-
3-
func friendRequests(n int, restrictions [][]int, requests [][]int) []bool {
4-
p = make([]int, n)
5-
for i := 0; i < n; i++ {
1+
func friendRequests(n int, restrictions [][]int, requests [][]int) (ans []bool) {
2+
p := make([]int, n)
3+
for i := range p {
64
p[i] = i
75
}
8-
var ans []bool
6+
var find func(int) int
7+
find = func(x int) int {
8+
if p[x] != x {
9+
p[x] = find(p[x])
10+
}
11+
return p[x]
12+
}
913
for _, req := range requests {
10-
u, v := req[0], req[1]
11-
if find(u) == find(v) {
14+
pu, pv := find(req[0]), find(req[1])
15+
if pu == pv {
1216
ans = append(ans, true)
1317
} else {
14-
valid := true
15-
for _, res := range restrictions {
16-
x, y := res[0], res[1]
17-
if (find(u) == find(x) && find(v) == find(y)) || (find(u) == find(y) && find(v) == find(x)) {
18-
valid = false
18+
ok := true
19+
for _, r := range restrictions {
20+
px, py := find(r[0]), find(r[1])
21+
if px == pu && py == pv || px == pv && py == pu {
22+
ok = false
1923
break
2024
}
2125
}
22-
ans = append(ans, valid)
23-
if valid {
24-
p[find(u)] = find(v)
26+
ans = append(ans, ok)
27+
if ok {
28+
p[pv] = pu
2529
}
2630
}
2731
}
28-
return ans
29-
}
30-
31-
func find(x int) int {
32-
if p[x] != x {
33-
p[x] = find(p[x])
34-
}
35-
return p[x]
32+
return
3633
}

‎solution/2000-2099/2076.Process Restricted Friend Requests/Solution.java

+15-17
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,25 @@ public boolean[] friendRequests(int n, int[][] restrictions, int[][] requests) {
66
for (int i = 0; i < n; ++i) {
77
p[i] = i;
88
}
9-
boolean[] ans = new boolean[requests.length];
10-
int i = 0;
11-
for (int[] req : requests) {
12-
int u = req[0], v = req[1];
13-
if (find(u) == find(v)) {
14-
ans[i++] = true;
9+
int m = requests.length;
10+
boolean[] ans = new boolean[m];
11+
for (int i = 0; i < m; ++i) {
12+
int u = requests[i][0], v = requests[i][1];
13+
int pu = find(u), pv = find(v);
14+
if (pu == pv) {
15+
ans[i] = true;
1516
} else {
16-
boolean valid = true;
17-
for (int[] res : restrictions) {
18-
int x = res[0], y = res[1];
19-
if ((find(u) == find(x) && find(v) == find(y))
20-
|| (find(u) == find(y) && find(v) == find(x))) {
21-
valid = false;
17+
boolean ok = true;
18+
for (var r : restrictions) {
19+
int px = find(r[0]), py = find(r[1]);
20+
if ((pu == px && pv == py) || (pu == py && pv == px)) {
21+
ok = false;
2222
break;
2323
}
2424
}
25-
if (valid) {
26-
p[find(u)] = find(v);
27-
ans[i++] = true;
28-
} else {
29-
ans[i++] = false;
25+
if (ok) {
26+
ans[i] = true;
27+
p[pu] = pv;
3028
}
3129
}
3230
}

‎solution/2000-2099/2076.Process Restricted Friend Requests/Solution.py

+11-13
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,25 @@ class Solution:
22
def friendRequests(
33
self, n: int, restrictions: List[List[int]], requests: List[List[int]]
44
) -> List[bool]:
5-
p = list(range(n))
6-
7-
def find(x):
5+
def find(x: int) -> int:
86
if p[x] != x:
97
p[x] = find(p[x])
108
return p[x]
119

10+
p = list(range(n))
1211
ans = []
13-
i = 0
1412
for u, v in requests:
15-
if find(u) == find(v):
13+
pu, pv = find(u), find(v)
14+
if pu == pv:
1615
ans.append(True)
1716
else:
18-
valid = True
17+
ok = True
1918
for x, y in restrictions:
20-
if (find(u) == find(x) and find(v) == find(y)) or (
21-
find(u) == find(y) and find(v) == find(x)
22-
):
23-
valid = False
19+
px, py = find(x), find(y)
20+
if (pu == px and pv == py) or (pu == py and pv == px):
21+
ok = False
2422
break
25-
ans.append(valid)
26-
if valid:
27-
p[find(u)] = find(v)
23+
ans.append(ok)
24+
if ok:
25+
p[pu] = pv
2826
return ans
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function friendRequests(n: number, restrictions: number[][], requests: number[][]): boolean[] {
2+
const p: number[] = Array.from({ length: n }, (_, i) => i);
3+
const find = (x: number): number => {
4+
if (p[x] !== x) {
5+
p[x] = find(p[x]);
6+
}
7+
return p[x];
8+
};
9+
const ans: boolean[] = [];
10+
for (const [u, v] of requests) {
11+
const pu = find(u);
12+
const pv = find(v);
13+
if (pu === pv) {
14+
ans.push(true);
15+
} else {
16+
let ok = true;
17+
for (const [x, y] of restrictions) {
18+
const px = find(x);
19+
const py = find(y);
20+
if ((px === pu && py === pv) || (px === pv && py === pu)) {
21+
ok = false;
22+
break;
23+
}
24+
}
25+
ans.push(ok);
26+
if (ok) {
27+
p[pu] = pv;
28+
}
29+
}
30+
}
31+
return ans;
32+
}

0 commit comments

Comments
 (0)
Please sign in to comment.