LeetCode #886 Possible Bipartition 可能的二分法 886 Possible Bipartition 可能的二分法

886 Possible Bipartition 可能的二分法

Description:
We want to split a group of n people (labeled from 1 to n) into two groups of any size. Each person may dislike some other people, and they should not go into the same group.

Given the integer n and the array dislikes where dislikes[i] = [ai, bi] indicates that the person labeled ai does not like the person labeled bi, return true if it is possible to split everyone into two groups in this way.

Example:

Example 1:

Input: n = 4, dislikes = [[1,2],[1,3],[2,4]]
Output: true
Explanation: group1 [1,4] and 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 <= 10^4
dislikes[i].length == 2
1 <= dislikes[i][j] <= n
ai < bi
All the pairs of dislikes are unique.

題目描述:
給定一組 N 人(編號爲 1, 2, ..., N), 我們想把每個人分進任意大小的兩組。

每個人都可能不喜歡其他人,那麼他們不應該屬於同一組。

形式上,如果 dislikes[i] = [a, b],表示不允許將編號爲 a 和 b 的人歸入同一組。

當可以用這種方法將所有人分進兩組時,返回 true;否則返回 false。

示例 :

示例 1:

輸入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
輸出:true
解釋:group1 [1,4], group2 [2,3]

示例 2:

輸入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
輸出:false

示例 3:

輸入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
輸出:false

提示:

1 <= N <= 2000
0 <= dislikes.length <= 10000
dislikes[i].length == 2
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
對於 dislikes[i] == dislikes[j] 不存在 i != j

思路:

DFS ➕ 染色
給定 color 數組, 0 表示未染色, 正負 1 表示兩種不同的顏色
在 DFS 過程中, 如果相鄰結點顏色相同, 則返回 false
檢查完所有人返回 true
時間複雜度爲 O(n + m), 空間複雜度爲 O(n + m), 其中 m 爲 dislikes 數組的長度

代碼:
C++:

class Solution 
{
public:
    bool possibleBipartition(int n, vector<vector<int>>& dislikes) 
    {
        vector<vector<int>> graph(n + 1);
        for (const auto& d : dislikes)
        {
            graph[d[0]].emplace_back(d[1]);
            graph[d[1]].emplace_back(d[0]);
        }
        vector<int> color(n + 1,0);
        function<bool(int, int)> dfs = [&](int cur_node, int col)
        {
            if (color[cur_node]) return color[cur_node] == col;
            color[cur_node] = col;
            for (const auto& next_node : graph[cur_node]) if(!dfs(next_node, -col)) return false;
            return true;
        };
        for (int i = 1; i <= n; i++) if (!color[i] and !dfs(i, 1)) return false;
        return true;
    }
};

Java:

class Solution {
    public boolean possibleBipartition(int n, int[][] dislikes) {
        List<List<Integer>> graph = new ArrayList<>();
        for (int i = 0; i <= n; i++) graph.add(new ArrayList<Integer>());
        for (int d[] : dislikes) {
            graph.get(d[0]).add(d[1]);
            graph.get(d[1]).add(d[0]);
        }
        int color[] = new int[n + 1];
        for (int i = 1; i <= n; i++) if (color[i] == 0 && !dfs(i, 1, color, graph)) return false;
        return true;
    }
    
    private boolean dfs(int curNode, int col, int[] color, List<List<Integer>> graph) {
        if (color[curNode] != 0) return color[curNode] == col;
        color[curNode] = col;
        for (int nextNode : graph.get(curNode)) if(!dfs(nextNode, -col, color, graph)) return false;
        return true;
    }
}

Python:

class Solution:
    def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
        graph, color = defaultdict(list), [0] * (n + 1)
        for d in dislikes:
            graph[d[0]].append(d[1])
            graph[d[1]].append(d[0])
            
        def dfs(cur_node: int, col: int) -> bool:
            if color[cur_node]:
                return color[cur_node] == col
            color[cur_node] = col
            for next_node in graph[cur_node]:
                if not dfs(next_node, -col):
                    return False
            return True
        for i in range(1, n + 1):
            if not color[i] and not dfs(i, 1):
                return False
        return True
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章