886. Possible Bipartition

在这里插入图片描述

这题是自己的知识盲区。
自己做了没有做出来,而且认为我的思路是正确的,找不出错误在哪儿,错误代码在最下面,希望以后能够找出来错误在哪儿吧。

首先这一题一开始最重要的思路,也是自己没有想到的,就是把一对一的不喜欢的关系转换为邻接表,也就是看成图的问题。这自己没有想到确实不应该。一直有些苦恼的怎么快速找到不喜欢的关系的问题用邻接表可以轻松解决。
然后思路应该是这样:对于每一个还没有确定在哪个group里面的,将它放入任意一个group,然后将它所有和它相邻的(不喜欢的)放入另一个group,再将与它们相邻的放入另一个group,一直这样下去,所以需要一个queue。也就是每次处理完一整个互相有关系的人群。

class Solution {
public:
    bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
        vector<vector<int>> adj(N+1, vector<int>());//用个邻接表把关系表示出来。用空间换取效率。这是很重要的思路
        for (auto& dislike : dislikes) {
            adj[dislike[0]].push_back(dislike[1]);
            adj[dislike[1]].push_back(dislike[0]);
        }
        
        vector<int> colors(N+1, 0);
        queue<int> q;
        for (int i = 1; i <= N; ++i) {
            if (colors[i] != 0)
                continue;
            colors[i] = 1;//对于一个新的来说,放进哪个都是一样的
            q.push(i);
            while (!q.empty()) {
                int cur = q.front();
                q.pop();
                for (int nb : adj[cur]) {
                    if (colors[nb] == 0) {
                        colors[nb] = colors[cur] == 1? 2 : 1;
                        q.push(nb);
                    } else {
                        if (colors[nb] == colors[cur])
                            return false;
                    }
                }
            }
        }
        return true;
    }
};

这是bfs,应该可以用dfs:

class Solution {
public:
    bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
        vector<vector<int>> adj(N+1, vector<int>());//用个邻接表把关系表示出来。用空间换取效率。这是很重要的思路
        for (auto& dislike : dislikes) {
            adj[dislike[0]].push_back(dislike[1]);
            adj[dislike[1]].push_back(dislike[0]);
        }
        
        vector<int> colors(N+1, 0);
        for (int i = 1; i <= N; ++i)
            if (colors[i] == 0)
                if (!dfs(adj, colors, i, 1))
                    return false;
        return true;
    }
private:
    bool dfs(vector<vector<int>>& adj, vector<int>& colors, int idx, int color) {
        if (colors[idx] != 0) {
            if (colors[idx] == color)
                return true;
            else
                return false;
        }
        colors[idx] = color;
        for (int nb : adj[idx])
            if (!dfs(adj, colors, nb, 3-color))
                return false;
        return true;
    }
};

然后这里是我一开始的思路的解法,主要的缺点就是没有用邻接表,但是我认为思路应该是正确的,不知道为什么不对。

class Solution {
public:
    bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
        unordered_set<int> s1, s2;
        return dfs(dislikes, 0, s1, s2);
    }
private:
    bool dfs(vector<vector<int>>& dislikes, int idx, unordered_set<int>& s1, unordered_set<int>& s2) {
        if (idx == dislikes.size())
            return true;
        auto& dislike = dislikes[idx];
        int num1 = dislike[0], num2 = dislike[1];
        if ((isInSet(num1, s1) && isInSet(num2, s1)) || (isInSet(num1, s2) && isInSet(num2, s2)))
            return false;
        if ((isInSet(num1, s1) && isInSet(num2, s2)) || (isInSet(num1, s2) && isInSet(num2, s1)))
            return dfs(dislikes, idx+1, s1, s2);
        if (isInSet(num1, s1)) {
            s2.insert(num2);
            if (dfs(dislikes, idx+1, s1, s2))
                return true;
            s2.erase(num2);
            return false;
        }
        if (isInSet(num2, s1)) {
            s2.insert(num1);
            if (dfs(dislikes, idx+1, s1, s2))
                return true;
            s2.erase(num1);
            return false;
        }
        if (isInSet(num1, s2)) {
            s1.insert(num2);
            if (dfs(dislikes, idx+1, s1, s2))
                return true;
            s1.erase(num2);
            return false;
        }
        if (isInSet(num2, s2)) {
            s1.insert(num1);
            if (dfs(dislikes, idx+1, s1, s2))
                return true;
            s1.erase(num1);
            return false;
        }
        s1.insert(num1);
        s2.insert(num2);
        if (dfs(dislikes, idx+1, s1, s2))
            return true;
        s1.erase(num1);
        s1.insert(num2);
        s2.erase(num2);
        s2.insert(num1);
        return dfs(dislikes, idx+1, s1, s2);
    }
    
    bool isInSet(int num, unordered_set<int>& s) {
        return s.find(num) != s.end();
    }
};

另外,785题和这题一样,可以看一眼

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值