LeetCode算法题——Is Graph Bipartite?

问题概述

Given a graph, return true if and only if it is bipartite.

Recall that a graph is bipartite if we can split it's set of nodes into two independent subsets A and B such that every edge in the graph has one node in A and another node in B.

The graph is given in the following form: graph[i] is a list of indexes j for which the edge between nodes i and j exists. Each node is an integer between 0 and graph.length - 1. There are no self edges or parallel edges: graph[i] does not contain i, and it doesn't contain any element twice.

Example:

Input: [[1,3], [0,2], [1,3], [0,2]]
Output: true
Explanation: 
The graph looks like this:
0----1
|    |
|    |
3----2
We can divide the vertices into two groups: {0, 2} and {1, 3}.

Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false
Explanation: 
The graph looks like this:
0----1
| \  |
|  \ |
3----2
We cannot find a way to divide the set of nodes into two independent ubsets.

分析

首次接触二分图,我们需要先明确二分图的定义以及性质。从题干得知,将二分图的结点划分归入两个子集A和B,则每一条图上的边都将连接一个A中的结点与一个B中的结点。换言之,每一个结点与其相邻点之间都应该是来自不同子集,因为它们由一条边连结。

有了这个性质,我们可以引入一个染色思想,即将来自不同子集的结点染上不同的颜色。由于题目要求判断一张图是否为二分图,问题便转变了为遍历逐个结点,判断其邻结点是否满足染色要求。如果一张图不是二分图,那么一定存在至少一个结点,这个结点的其中一个邻结点和这个结点颜色一致。我们可以由于题目传入的参数中已经给出了图的构造,即每个结点的邻结点,我们可以尝试使用DFS或BFS进行遍历,这里使用DFS来解题。

完整代码如下:

public boolean isBipartite(int[][] graph) {
        // 存储图上每个结点的染色信息
        int[] colors = new int[graph.length];
        // 定义-1为未染色;染色时分别用0和1表示两种颜色
        Arrays.fill(colors, -1); 
        
        for (int i = 0; i < graph.length; i++)
            if (colors[i] == -1 && !validColor(graph, colors, 0, i))
                return false;
        return true;
    }
    
    public boolean validColor(int[][] graph, int[] colors, int color, int node) {
        // 已经染色的点,颜色应该符合预期,否则便不是二分图
        if (colors[node] != -1)
            return colors[node] == color; 
        colors[node] = color; // 进行染色
        // 进行DFS,遍历当前结点的邻点,颜色与邻点相同则不是二分图
        for (int next : graph[node]) 
            if (!validColor(graph, colors, 1-color, next))
                return false;
        return true;
    }

总结

二分图具有诸多重要性质,运用染色思想去判断二分图直观易懂;同时这一过程中需要用到DFS/BFS等思想,解法中出于易理解的目的使用了递归方式来实现DFS,但可能增大了部分时间复杂度。

你可能感兴趣的:(LeetCode算法题——Is Graph Bipartite?)