Skip to content

Latest commit

 

History

History
228 lines (167 loc) · 4.73 KB

File metadata and controls

228 lines (167 loc) · 4.73 KB

中文文档

Description

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:

Input: N = 4, dislikes = [[1,2],[1,3],[2,4]]

Output: true

Explanation: group1 [1,4], group2 [2,3]

Example 2:

Input: N = 3, dislikes = [[1,2],[1,3],[2,3]]

Output: false

Example 3:

Input: N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]

Output: false

 

Constraints:

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

Solutions

Union find.

Python3

class Solution:
    def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
        p = list(range(n))

        def find(x):
            if p[x] != x:
                p[x] = find(p[x])
            return p[x]

        mp = collections.defaultdict(list)
        for i, j in dislikes:
            mp[i - 1].append(j - 1)
            mp[j - 1].append(i - 1)
        for i in range(n):
            dis = mp[i]
            for j in dis:
                if find(i) == find(j):
                    return False
                p[find(j)] = find(dis[0])
        return True

Java

class Solution {
public:
    vector<int> p;

    bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
        p.resize(n);
        for (int i = 0; i < n; ++i) p[i] = i;
        unordered_map<int, vector<int>> mp;
        for (auto e : dislikes)
        {
            mp[e[0] - 1].push_back(e[1] - 1);
            mp[e[1] - 1].push_back(e[0] - 1);
        }
        for (int i = 0; i < n; ++i)
        {
            auto dis = mp[i];
            for (int j : dis)
            {
                if (find(i) == find(j)) return false;
                p[find(j)] = find(dis[0]);
            }
        }
        return true;
    }

    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
};

C++

class Solution {
public:
    vector<int> p;

    bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
        p.resize(n);
        for (int i = 0; i < n; ++i) p[i] = i;
        unordered_map<int, vector<int>> mp;
        for (auto e : dislikes)
        {
            mp[e[0] - 1].push_back(e[1] - 1);
            mp[e[1] - 1].push_back(e[0] - 1);
        }
        for (int i = 0; i < n; ++i)
        {
            auto dis = mp[i];
            for (int j : dis)
            {
                if (find(i) == find(j)) return false;
                p[find(j)] = find(dis[0]);
            }
        }
        return true;
    }

    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
};

Go

var p []int

func possibleBipartition(n int, dislikes [][]int) bool {
	p = make([]int, n)
	for i := 0; i < n; i++ {
		p[i] = i
	}
	mp := make(map[int][]int)
	for _, e := range dislikes {
		mp[e[0]-1] = append(mp[e[0]-1], e[1]-1)
		mp[e[1]-1] = append(mp[e[1]-1], e[0]-1)
	}
	for i := 0; i < n; i++ {
		dis := mp[i]
		for _, j := range dis {
			if find(i) == find(j) {
				return false
			}
			p[find(j)] = find(dis[0])
		}
	}
	return true
}

func find(x int) int {
	if p[x] != x {
		p[x] = find(p[x])
	}
	return p[x]
}

...