zoukankan      html  css  js  c++  java
  • [LeetCode] 886. Possible Bipartition

    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].

    可能的二分法。

    题意是给一个数字N代表有N个人,还有一个二维数组dislikes,代表每两个人之间的dislike关系。请返回是否有可能将N个人分成两组。

    这个题实际是在考能否将一个图的节点分成两组。有几种不同的思路,但是相同点都是通过染色的方式来判断是否能被二分。我这里给出一个DFS的做法。首先创建一个长度为N的额外数组,记录每个节点的涂色状况。我这里是把两组人一组设置成0,一组设置成1,初始化的时候所有人都是-1。再来是通过dislikes里面的关系,将input构建成一个图,我这里是用一个邻接表记录的。

    开始遍历input,如果当前这个人是-1的话,则开始dfs遍历。dfs遍历的时候去检查,如果当前这个人dislike的另一个人(也就是当前这个人的邻居)已经被染成同一种颜色,则return false;同时,如果当前的人的邻居没有被染色但是当这个邻居的邻居之间有同色的情形,也return false。

    时间O(V + E)

    空间O(n^2) - 记录了graph

    Java实现

     1 class Solution {
     2     public boolean possibleBipartition(int N, int[][] dislikes) {
     3         // corner case
     4         if (dislikes == null || dislikes.length == 0) {
     5             return true;
     6         }
     7 
     8         // normal case
     9         List<List<Integer>> graph = buildGraph(N, dislikes);
    10         // 开一个数组表示每个顶点的颜色。-1表示未访问,0和1分别表示两种颜色
    11         int[] colors = new int[N];
    12         Arrays.fill(colors, -1);
    13         for (int i = 0; i < N; i++) {
    14             if (colors[i] == -1) {
    15                 if (!dfs(i, graph, colors, 0)) {
    16                     return false;
    17                 }
    18             }
    19         }
    20         return true;
    21     }
    22 
    23     // 从cur开始做DFS,并将cur染色为color
    24     private boolean dfs(int cur, List<List<Integer>> graph, int[] colors, int color) {
    25         colors[cur] = color;
    26         for (int next : graph.get(cur)) {
    27             // 如果发现某个邻居的颜色和自己一样,则返回false
    28             if (colors[next] == color) {
    29                 return false;
    30             }
    31             // 若发现next遍历后会发现某两个邻居染色一样,也返回false
    32             if (colors[next] == -1 && !dfs(next, graph, colors, color ^ 1)) {
    33                 return false;
    34             }
    35         }
    36         return true;
    37     }
    38 
    39     private List<List<Integer>> buildGraph(int N, int[][] dislikes) {
    40         List<List<Integer>> graph = new ArrayList<>(N);
    41         for (int i = 0; i < N; i++) {
    42             graph.add(new ArrayList<>());
    43         }
    44         for (int[] dislike : dislikes) {
    45             graph.get(dislike[0] - 1).add(dislike[1] - 1);
    46             graph.get(dislike[1] - 1).add(dislike[0] - 1);
    47         }
    48         return graph;
    49     }
    50 }

    相关题目

    785. Is Graph Bipartite

    886. Possible Bipartition

    LeetCode 题目总结

  • 相关阅读:
    ubuntu16.04下docker安装和简单使用(转)
    spring security There was an unexpected error (type=Forbidden, status=403).
    笔记42 Spring Web Flow——Demo(2)
    Idea debug时报错:Command line is too long
    特殊字符(包括emoji)梳理和UTF8编码解码原理(转)
    如何理解多租户架构?(转)
    Android Studio使用阿里云Aliyun Maven仓库
    解决 INSTALL FAILED CONFLICTING PROVIDER
    Android解决冲突
    Mysql查询库、表存储量(Size)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12977970.html
Copyright © 2011-2022 走看看