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進行紅藍着色的,感興趣的可以參考這裏

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