LeetCode 886. Possible Bipartition

Problem

LeetCode 886. Possible Bipartition

1. 题目简述

给出n个人,编号从(1…n),我们可以将他们分成任意大小的两组,但是他们之间会有讨厌某些人的关系,那么他们就不用管被分到同一个组里。

用公式化的形式来讲,就是如果dislikes[i] = [a, b],那么a和b就不会被分到同一个组里。我们需要判断能否做到合适的分组,满足所有dislike条件。

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

2. 算法思路

经典的二分图算法,和785是一样的,只不过本题需要先把整张dislike图给construct出来。染色,然后判断是否ok。

DFS

BFS

注意

首先将整张dislike图build出来,因为我们并不知道每个人究竟有多少个dislike的对象,所以可以用ArrayList的数组来存储。这里需要注意ArrayList数组的初始化问题!!!ArrayList数组应该这样初始化,注释中的做法不可用!!!

原因在于foreach不能用于元素赋值或初始化,而是将数组中元素copy一份给临时变量。


ArrayList<Integer>[] dislikeGraph = new ArrayList[N + 1];

// for (List<Integer> list : dislikeGraph) {
//     list = new ArrayList();
// }

for (int i = 0; i <= N; i++) {
    dislikeGraph[i] = new ArrayList();
}

3. 解法

DFS


class Solution {
        // 注意List数组的创建!!!
        ArrayList<Integer>[] dislikeGraph = new ArrayList[N + 1];

        for (int i = 0; i <= N; i++) {
            dislikeGraph[i] = new ArrayList();
        }

        for (int[] dislike : dislikes) {
            dislikeGraph[dislike[0]].add(dislike[1]);
            dislikeGraph[dislike[1]].add(dislike[0]);
        }

        // DFS, -1是未访问,0是red,1是black
        int[] isVisited = new int[N + 1];
        Arrays.fill(isVisited, -1);

        for (int i = 1; i <= N; i++) {
            if (isVisited[i] != -1) {
                continue;
            }
            // 注意这里给上的颜色,如果已经遍历过,有颜色,则说明该节点没问题,跳过即可
            isVisited[i] = 0;
            if (!dfs(dislikeGraph, isVisited, i)) {
                return false;
            }
        }

        return true;
    }

    private boolean dfs(List<Integer>[] dislikeGraph, int[] isVisited, int index) {
        for (int i : dislikeGraph[index]) {
            if (isVisited[i] == -1) {
                isVisited[i] = isVisited[index] ^ 1;
                if (!dfs(dislikeGraph, isVisited, i)) {
                    return false;
                }
            } else if (isVisited[i] != (isVisited[index] ^ 1)) {
                return false;
            }
        }

        return true;
    }
}

BFS:
下次看到这里再留着练手吧