Skip to content

Commit

Permalink
add solution for #886 Possible Bipartition.
Browse files Browse the repository at this point in the history
  • Loading branch information
ecgan committed May 30, 2020
1 parent 7199fc0 commit d03d086
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
55 changes: 55 additions & 0 deletions problems/possible-bipartition/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Possible Bipartition

LeetCode #: [886](https://leetcode.com/problems/possible-bipartition/)

Difficulty: Medium

Topics: Depth-first Search.

## Problem

Given a set of `N` people (numbered `1, 2, ..., N`), we would like to split everyone into two groups of any size.

Each person may dislike some other people, and they should not go into the same group.

Formally, if `dislikes[i] = [a, b]`, it means it is not allowed to put the people numbered `a` and `b` into the same group.

Return `true` if and only if it is possible to split everyone into two groups in this way.

Example 1:

```text
Input: N = 4, dislikes = [[1,2],[1,3],[2,4]]
Output: true
Explanation: group1 [1,4], group2 [2,3]
```

Example 2:

```text
Input: N = 3, dislikes = [[1,2],[1,3],[2,3]]
Output: false
```

Example 3:

```text
Input: N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
Output: false
```

Note:

- `1 <= N <= 2000`
- `0 <= dislikes.length <= 10000`
- `1 <= dislikes[i][j] <= N`
- `dislikes[i][0] < dislikes[i][1]`
- There does not exist `i != j` for which `dislikes[i] == dislikes[j]`.

## Complexity Analysis

Assume E is the length of `dislikes` array.

Time complexity: O(N+E).

Space complexity: O(N+E).
57 changes: 57 additions & 0 deletions problems/possible-bipartition/possibleBipartition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const getDfsFn = (lists, numGroupMap) => {
const dfs = (num, group) => {
if (numGroupMap.has(num)) {
return numGroupMap.get(num) === group
}

numGroupMap.set(num, group)

const dislikes = lists[num] || []
for (let i = 0; i < dislikes.length; i++) {
if (!dfs(dislikes[i], group ^ 1)) {
return false
}
}

return true
}

return dfs
}

const getDislikesLists = (dislikes) => {
const lists = []

for (let i = 0; i < dislikes.length; i++) {
const [a, b] = dislikes[i]

lists[a] = lists[a] || []
lists[a].push(b)

lists[b] = lists[b] || []
lists[b].push(a)
}

return lists
}

/**
* @param {number} N
* @param {number[][]} dislikes
* @return {boolean}
*/
const possibleBipartition = function (N, dislikes) {
const lists = getDislikesLists(dislikes)
const numGroupMap = new Map()
const dfs = getDfsFn(lists, numGroupMap)

for (let i = 1; i <= N; i++) {
if (!numGroupMap.has(i) && !dfs(i, 0)) {
return false
}
}

return true
}

module.exports = possibleBipartition
37 changes: 37 additions & 0 deletions problems/possible-bipartition/possibleBipartition.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const possibleBipartition = require('./possibleBipartition')

test('Example 1', () => {
const N = 4
const dislikes = [[1, 2], [1, 3], [2, 4]]

const result = possibleBipartition(N, dislikes)

expect(result).toBe(true)
})

test('Example 2', () => {
const N = 3
const dislikes = [[1, 2], [1, 3], [2, 3]]

const result = possibleBipartition(N, dislikes)

expect(result).toBe(false)
})

test('Example 3', () => {
const N = 5
const dislikes = [[1, 2], [2, 3], [3, 4], [4, 5], [1, 5]]

const result = possibleBipartition(N, dislikes)

expect(result).toBe(false)
})

test('N=1, no dislikes', () => {
const N = 1
const dislikes = []

const result = possibleBipartition(N, dislikes)

expect(result).toBe(true)
})

0 comments on commit d03d086

Please sign in to comment.