首页
Preview

每日 LeetCode 题目:问题 785. 是否为二分图?

简介:

图论是计算机科学和数学中的一个基本主题。它提供了一个强大的框架来建模实体之间的关系。LeetCode提供了各种与图相关的问题,以挑战我们的理解和问题解决能力。在本文中,我们将深入探讨问题758,“是否为二分图?”,并探索一种有效的算法来确定给定图形是否为二分图。

问题陈述:

该问题提供了一个无向图,具有n个节点,由2D数组图表示。每个节点的编号从0到n-1,并且graph [u]表示与节点u相邻的节点数组。图满足某些属性:没有自环,没有平行边,以及无向性。任务是确定图是否为二分图,其中节点可以分为两个独立的集合,使得每条边连接来自不同集合的节点。

方法:

为了解决这个问题,我们可以利用图着色的概念,并在图上执行深度优先搜索(DFS)。关键思想是为节点分配颜色,使相邻节点具有不同的颜色。如果在着色过程中遇到矛盾,我们可以得出结论,即该图不是二分图。

伪代码:

  • 初始化一个数组以存储每个节点的颜色。将所有节点设置为0(未分配颜色)。

  • 遍历图中的每个节点。

  • 如果当前节点未分配(color [node] == 0),则从该节点开始进行DFS。

  • 在DFS函数内部:

  • 为当前节点分配颜色(1或-1)。

  • 遍历相邻节点。

  • 如果相邻节点未分配,则使用相反的颜色递归调用DFS函数。

  • 如果相邻节点具有与当前节点相同的颜色,则返回false(不是二分图)。

  • 如果DFS函数在没有矛盾的情况下完成,则返回true(二分图)。

实现:

class Solution:
    def isBipartite(self, graph: List[List[int]]) -> bool:
        colors = [0] * len(graph)

        def dfs(node, color):
            colors[node] = color
            for neighbor in graph[node]:
                if colors[neighbor] == color:
                    return False
                if colors[neighbor] == 0 and not dfs(neighbor, -color):
                    return False
            return True

        for i in range(len(graph)):
            if colors[i] == 0 and not dfs(i, 1):
                return False
        return True

复杂度分析:

  • 时间复杂度:算法一次访问每个节点并探索其邻居,导致时间复杂度为O(V + E),其中V是图中的顶点数,E是边数。
  • 空间复杂度:空间复杂度为O(V),其中V是顶点数。这是必需的,以存储每个节点的颜色。

解决方案

Python

class Solution:
    def isBipartite(self, graph):
        n = len(graph)
        colors = [0] * n

        for i in range(n):
            if colors[i] == 0:
                if not self.dfs(graph, colors, i, 1):
                    return False

        return True

    def dfs(self, graph, colors, node, color):
        if colors[node] != 0:
            return colors[node] == color

        colors[node] = color

        for neighbor in graph[node]:
            if not self.dfs(graph, colors, neighbor, -color):
                return False

        return True

解释:

  • isBipartite函数检查给定的图是否为二分图。
  • dfs函数在图上执行深度优先搜索(DFS),为节点分配颜色并检查矛盾。

isBipartite函数中:

  • n变量表示图中的节点数。
  • colors列表初始化为零,将用于跟踪每个节点的颜色分配。
  • 函数使用for循环遍历图中的每个节点。
  • 对于每个未访问的节点(当colors [i] == 0时),它调用dfs函数从该节点开始执行DFS。
  • 如果在任何迭代期间dfs函数返回False,表示着色中存在矛盾,则该函数立即返回False。
  • 如果for循环完成而没有任何矛盾,则该函数返回True,表示该图为二分图。

dfs函数中:

  • graph参数表示输入图。
  • colors参数是跟踪每个节点的颜色分配的列表。
  • node参数是正在处理的当前节点。
  • color参数是分配给当前节点的颜色。
  • 该函数首先检查当前节点的颜色是否已分配(当colors [node]!= 0时)。
  • 如果颜色已分配,则如果分配的颜色与当前颜色匹配,则返回True,否则返回False。
  • 如果颜色未分配,则将当前颜色分配给节点(colors [node] = color)。
  • 然后,该函数对当前节点的每个邻居进行递归调用,传递相反的颜色(-color)。
  • 如果任何递归调用返回False,表示着色中存在矛盾,则该函数返回False。
  • 如果所有递归调用完成而没有任何矛盾,则该函数返回True。

Java

class Solution {
    public boolean isBipartite(int[][] graph) {
        int n = graph.length;
        int[] colors = new int[n];

        for (int i = 0; i < n; i++) {
            if (colors[i] == 0 && !dfs(graph, colors, i, 1)) {
                return false;
            }
        }

        return true;
    }

    private boolean dfs(int[][] graph, int[] colors, int node, int color) {
        if (colors[node] != 0) {
            return colors[node] == color;
        }

        colors[node] = color;

        for (int neighbor : graph[node]) {
            if (!dfs(graph, colors, neighbor, -color)) {
                return false;
            }
        }

        return true;
    }
}

C++

class Solution {
public:
    bool isBipartite(vector<vector<int>>& graph) {
        int n = graph.size();
        vector<int> colors(n, 0);

        for (int i = 0; i < n; i++) {
            if (colors[i] == 0 && !dfs(graph, colors, i, 1)) {
                return false;
            }
        }

        return true;
    }

private:
    bool dfs(vector<vector<int>>& graph, vector<int>& colors, int node, int color) {
        if (colors[node] != 0) {
            return colors[node] == color;
        }

        colors[node] = color;

        for (int neighbor : graph[node]) {
            if (!dfs(graph, colors, neighbor, -color)) {
                return false;
            }
        }

        return true;
    }
};

结论:

在本文中,我们探讨了LeetCode问题758,“是否为二分图?”,并提出了使用图着色和深度优先搜索的有效解决方案。通过利用二分性原理,我们可以确定给定的图是否可以分为两个独立的集合。理解图论和算法对于解决与图相关的问题至关重要,这个问题是应用这些概念的有价值的练习。

译自:https://medium.com/@_monitsharma/daily-leetcode-problems-problem-785-is-graph-bipartite-9e289095f576

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论