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 题目总结

  • 相关阅读:
    四、oracle 用户管理二
    三、oracle 用户管理一
    二、oracle sql*plus常用命令
    数据库的导入导出
    一:oracle系统包—-dbms_output用法
    数据库分类
    Oracle序列号详解
    Windows 下 java(JDK)的安装和环境变量的配置
    win7安装oracle 10g时发生“程序异常终止。发生内部错误”的提示
    对数据库列的操作
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12977970.html
Copyright © 2011-2022 走看看