LeetCode Daily challenge - Possible Bipartition

题目大意

将N个人划分为两组,每个人可能不喜欢其他人,即不能和不喜欢的分到一组,问是否能够成功划分。

输入

Ndislike[][2]分别表示人的个数和不喜欢的列表。例如N = 4, dislikes = [[1,2],[1,3],[2,4]],表示4个人,其中1与2,1与3,2与4不能分到同一组。

思路

类似并查集,因为不喜欢是成对出现的,所以记录每个元素所属的集合以及不喜欢的集合。对于不喜欢列表中的每一对(x, y),如若

  1. x,y都未加入任何集合 - 以他们自己为根元素初始化两个新集合,且x的不喜欢集合为y,y的不喜欢集合为x
  2. y未加入任何集合,x属于某个集合rootx - 将y加入到x的不喜欢集合中,将y的不喜欢集合设置为x
  3. x未加入任何集合,y属于某个集合rooty - 同上,将x加入到y的不喜欢集合,将x的不喜欢集合设置为y
  4. x,y都加入了某个集合rootx,rooty - 若rootx==rooty,则return false,无法划分

若最后一种情况未出现,则表示可以划分为两个集合

代码

struct T{
    int root, oproot;
    T(){ root = oproot = -1;}
    bool empty() { return root == -1; }
    void setRoot(int root, int oproot) { this->root = root, this->oproot = oproot; }
};
class Solution {
public:
    bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
        vector<T> roots(N + 1);
        for (auto tmpvec: dislikes) {
            int x = tmpvec[0], y = tmpvec[1];
            T &xt = roots[x], &yt = roots[y];
            if (xt.empty() && yt.empty()) {
                xt.setRoot(x, y);
                yt.setRoot(y, x);
            } else if (xt.empty()) {
                xt.setRoot(yt.oproot, yt.root);
            } else if (yt.empty()){
                yt.setRoot(xt.oproot, xt.root);
            } else {
                if (xt.root == yt.root) return false;
            }
        }
        return true;
    }
};

总结

讨论版中有以二分图为思路使用BFS进行红蓝着色的,感兴趣的可以参考这里

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章