Leetcode 886、可能的二分法

这篇博客介绍了如何解决LeetCode的第886题——可能的二分法,主要使用深度优先搜索(DFS)策略。通过建立邻接表并用颜色标记节点状态,博主详细解释了如何判断不喜欢关系是否允许进行二分划分。代码中,首先初始化颜色状态,然后遍历邻接表,通过DFS判断每个节点的颜色分配是否可行。最后,如果所有节点都能成功分配颜色,则返回二分法可行,否则不可行。该算法的时间和空间复杂度均为O(n+m),其中n是人数,m是不喜欢关系的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Leetcode 886、可能的二分法

在这里插入图片描述

DFS

思路

  • 使用颜色标识当前节点的状态, R 表示红色; B 表示蓝色; W 表示白色,即初始状态
  • 使用一个状态数组 status 来标识当前节点的颜色
  • 根据 dislike 数组构建邻接表 graph
  • dfs 方法里面,判断 pre 的值, currStatus 是 pre 的相反值,遍历当前节点的邻接链表:
  • 如果当前位置已经访问过了,如果颜色和 pre 一样,直接返回 false, 表示不可以进行二分;
  • 如果是 W ,说明没有被访问过,那么就把当前位置的状态设置为 currStatus
  • 最后返回结果

时间复杂度

  • O(n + m),其中 n 题目给定的人数,m 为给定的 dislike 数组的大小

空间复杂度

  • O(n + m),其中 n 题目给定的人数,m 为给定的 dislike 数组的大小

代码

public class PossibleBipartition {
    /**
     * 思路:DFS
     * 使用颜色标识当前节点的状态, R 表示红色; B 表示蓝色; W 表示白色,即初始状态
     * 使用一个状态数组 status 来标识当前节点的颜色
     * 根据 dislike 数组构建邻接表 graph
     * dfs 方法里面,判断 pre 的值, currStatus 是 pre 的相反值,遍历当前节点的邻接链表:
     * 如果当前位置已经访问过了,如果颜色和 pre 一样,直接返回 false, 表示不可以进行二分;
     * 如果是 W ,说明没有被访问过,那么就把当前位置的状态设置为 currStatus,
     * 最后返回结果
     *
     * 时间复杂度:O(n + m),其中 n 题目给定的人数,m 为给定的 dislike 数组的大小。
     * 空间复杂度:O(n + m),其中 n 题目给定的人数,m 为给定的 dislike 数组的大小。
     *
     * @param n
     * @param dislikes
     */
    public boolean possibleBipartition(int n, int[][] dislikes) {
        List<List<Integer>> graph = new ArrayList<>();
        for(int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }
        for(int i = 0; i < dislikes.length; i++) {
            graph.get(dislikes[i][0] - 1).add(dislikes[i][1] - 1);
            graph.get(dislikes[i][1] - 1).add(dislikes[i][0] - 1);
        }

        String[] status = new String[n];
        Arrays.fill(status, "W"); // R 表示红色, B 表示蓝色, W 表示白色,是初始状态

        for(int i = 0; i < graph.size(); i++) {
            if(status[i].equals("W")) {
                status[i] = "R";
                if(!dfs(status, graph, i, "R")) {
                    return false;
                }
            }
        }

        return true;
    }

    public boolean dfs(String[] status, List<List<Integer>> graph, int index, String pre) {
        String currStatus = "";
        if(pre.equals("R")) {
            currStatus = "B";
        }else {
            currStatus = "R";
        }

        List<Integer> curr = graph.get(index);
        for(int i = 0; i < curr.size(); i++) {
            if(status[curr.get(i)].equals("W")) {
                status[curr.get(i)] = currStatus;
                if(!dfs(status, graph, curr.get(i), currStatus)) return false;
            }else if(status[curr.get(i)].equals(pre)) {
                return false;
            }
        }

        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值