Skip to content

Commit 820d75f

Browse files
committed
feat: leetcode 886
1 parent 73b660f commit 820d75f

File tree

8 files changed

+149
-8
lines changed

8 files changed

+149
-8
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<p align="center">
44
<!-- TOPICS COUNT START -->
5-
<img src="https://img.shields.io/badge/-进度:521-green" alt="进度:521">
5+
<img src="https://img.shields.io/badge/-进度:522-green" alt="进度:522">
66
<!-- TOPICS COUNT END -->
77
<a href="./assets/docs/TOPICS.md"><img src="https://img.shields.io/badge/-题库目录-blue" alt="题库目录"></a>
88
<a href="./assets/docs/CATEGORIES.md"><img src="https://img.shields.io/badge/-题库分类-red" alt="题库分类"></a>

assets/data/categories.json

+12-6
Original file line numberDiff line numberDiff line change
@@ -3458,6 +3458,12 @@
34583458
"path": "./problemset/k-similar-strings/README.md",
34593459
"difficulty": "困难"
34603460
},
3461+
{
3462+
"id": "886",
3463+
"title": "可能的二分法",
3464+
"path": "./problemset/possible-bipartition/README.md",
3465+
"difficulty": "中等"
3466+
},
34613467
{
34623468
"id": "965",
34633469
"title": "单值二叉树",
@@ -3518,17 +3524,17 @@
35183524
"path": "./problemset/count-nodes-with-the-highest-score/README.md",
35193525
"difficulty": "中等"
35203526
},
3521-
{
3522-
"id": "面试题 04.06",
3523-
"title": "后继者",
3524-
"path": "./problemset/successor-lcci/README.md",
3525-
"difficulty": "中等"
3526-
},
35273527
{
35283528
"id": "剑指 Offer II 114",
35293529
"title": "外星文字典",
35303530
"path": "./problemset/alien-dictionary/README.md",
35313531
"difficulty": "困难"
3532+
},
3533+
{
3534+
"id": "面试题 04.06",
3535+
"title": "后继者",
3536+
"path": "./problemset/successor-lcci/README.md",
3537+
"difficulty": "中等"
35323538
}
35333539
]
35343540
},

assets/data/topics.json

+10
Original file line numberDiff line numberDiff line change
@@ -4049,6 +4049,16 @@
40494049
"url": "https://leetcode-cn.com/problems/uncommon-words-from-two-sentences/",
40504050
"path": "./problemset/uncommon-words-from-two-sentences/README.md"
40514051
},
4052+
{
4053+
"id": "886",
4054+
"title": {
4055+
"cn": "可能的二分法",
4056+
"en": "possible-bipartition"
4057+
},
4058+
"difficulty": "中等",
4059+
"url": "https://leetcode.cn/problems/possible-bipartition/",
4060+
"path": "./problemset/possible-bipartition/README.md"
4061+
},
40524062
{
40534063
"id": "890",
40544064
"title": {

assets/docs/CATEGORIES.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@
630630
| 814. [二叉树剪枝](../../problemset/binary-tree-pruning/README.md) | 中等 |
631631
| 838. [推多米诺](../../problemset/push-dominoes/README.md) | 中等 |
632632
| 854. [相似度为 K 的字符串](../../problemset/k-similar-strings/README.md) | 困难 |
633+
| 886. [可能的二分法](../../problemset/possible-bipartition/README.md) | 中等 |
633634
| 965. [单值二叉树](../../problemset/univalued-binary-tree/README.md) | 简单 |
634635
| 1020. [飞地的数量](../../problemset/number-of-enclaves/README.md) | 中等 |
635636
| 1022. [ 从根到叶的二进制数之和](../../problemset/sum-of-root-to-leaf-binary-numbers/README.md) | 简单 |
@@ -640,8 +641,8 @@
640641
| 1823. [找出游戏的获胜者](../../problemset/find-the-winner-of-the-circular-game/README.md) | 中等 |
641642
| 2039. [网络空闲的时刻](../../problemset/the-time-when-the-network-becomes-idle/README.md) | 中等 |
642643
| 2049. [统计最高分的节点数目](../../problemset/count-nodes-with-the-highest-score/README.md) | 中等 |
643-
| 面试题 04.06. [后继者](../../problemset/successor-lcci/README.md) | 中等 |
644644
| 剑指 Offer II 114. [外星文字典](../../problemset/alien-dictionary/README.md) | 困难 |
645+
| 面试题 04.06. [后继者](../../problemset/successor-lcci/README.md) | 中等 |
645646

646647
##
647648

assets/docs/TOPICS.md

+2
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,8 @@
810810

811811
[884. 两句话中的不常见单词](../../problemset/uncommon-words-from-two-sentences/README.md)
812812

813+
[886. 可能的二分法](../../problemset/possible-bipartition/README.md)
814+
813815
[890. 查找和替换模式](../../problemset/find-and-replace-pattern/README.md)
814816

815817
[899. 有序队列](../../problemset/orderly-queue/README.md)
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# 可能的二分法
2+
3+
> 难度:中等
4+
>
5+
> https://leetcode.cn/problems/possible-bipartition/
6+
7+
## 题目
8+
9+
给定一组 `n` 人(编号为 1, 2, ..., n), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。
10+
11+
给定整数 `n` 和数组 `dislikes` ,其中 `dislikes[i] = [ai, bi]` ,表示不允许将编号为 `ai` 和  `bi`的人归入同一组。当可以用这种方法将所有人分进两组时,返回 `true`;否则返回 `false`
12+
13+
### 示例
14+
15+
#### 示例 1:
16+
17+
```
18+
输入:n = 4, dislikes = [[1,2],[1,3],[2,4]]
19+
输出:true
20+
解释:group1 [1,4], group2 [2,3]
21+
```
22+
23+
#### 示例 2:
24+
25+
```
26+
输入:n = 3, dislikes = [[1,2],[1,3],[2,3]]
27+
输出:false
28+
```
29+
30+
#### 示例 3:
31+
32+
```
33+
输入:n = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
34+
输出:false
35+
```
36+
37+
## 解题
38+
39+
```ts
40+
/**
41+
* 深度优先搜索
42+
* @desc 时间复杂度 O(N+M) 空间复杂度 O(N+M)
43+
* @param n
44+
* @param dislikes
45+
* @returns
46+
*/
47+
export function possibleBipartition(n: number, dislikes: number[][]): boolean {
48+
const color = new Array<number>(n + 1).fill(0)
49+
const g: number[][] = new Array(n + 1).fill([]).map(() => [])
50+
51+
for (const p of dislikes) {
52+
g[p[0]].push(p[1])
53+
g[p[1]].push(p[0])
54+
}
55+
for (let i = 1; i <= n; ++i) {
56+
if (color[i] === 0 && !dfs(i, 1))
57+
return false
58+
}
59+
return true
60+
61+
function dfs(curnode: number, nowcolor: number) {
62+
color[curnode] = nowcolor
63+
for (const nextnode of g[curnode]) {
64+
if (color[nextnode] !== 0 && color[nextnode] === color[curnode])
65+
return false
66+
67+
if (color[nextnode] === 0 && !dfs(nextnode, 3 ^ nowcolor))
68+
return false
69+
}
70+
return true
71+
}
72+
}
73+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { possibleBipartition } from '.'
3+
4+
describe('可能的二分法', () => {
5+
testCase(possibleBipartition)
6+
})
7+
8+
function testCase(fn: typeof possibleBipartition) {
9+
it.each([
10+
[4, [[1, 2], [1, 3], [2, 4]], true],
11+
[3, [[1, 2], [1, 3], [2, 3]], false],
12+
[5, [[1, 2], [2, 3], [3, 4], [4, 5], [1, 5]], false],
13+
])('示例%#', (n, dislikes, expected) => {
14+
expect(fn(n, dislikes)).toBe(expected)
15+
})
16+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* 深度优先搜索
3+
* @desc 时间复杂度 O(N+M) 空间复杂度 O(N+M)
4+
* @param n
5+
* @param dislikes
6+
* @returns
7+
*/
8+
export function possibleBipartition(n: number, dislikes: number[][]): boolean {
9+
const color = new Array<number>(n + 1).fill(0)
10+
const g: number[][] = new Array(n + 1).fill([]).map(() => [])
11+
12+
for (const p of dislikes) {
13+
g[p[0]].push(p[1])
14+
g[p[1]].push(p[0])
15+
}
16+
for (let i = 1; i <= n; ++i) {
17+
if (color[i] === 0 && !dfs(i, 1))
18+
return false
19+
}
20+
return true
21+
22+
function dfs(curnode: number, nowcolor: number) {
23+
color[curnode] = nowcolor
24+
for (const nextnode of g[curnode]) {
25+
if (color[nextnode] !== 0 && color[nextnode] === color[curnode])
26+
return false
27+
28+
if (color[nextnode] === 0 && !dfs(nextnode, 3 ^ nowcolor))
29+
return false
30+
}
31+
return true
32+
}
33+
}

0 commit comments

Comments
 (0)