2020-06-08 LeetCode 990 等式方程的可滿足性 C++

題目:990. 等式方程的可滿足性

 給定一個由表示變量之間關係的字符串方程組成的數組,每個字符串方程 equations[i] 的長度爲 4,並採用兩種不同的形式之一:“a==b” 或 “a!=b”。在這裏,a 和 b 是小寫字母(不一定不同),表示單字母變量名。

 只有當可以將整數分配給變量名,以便滿足所有給定的方程時才返回 true,否則返回 false。

示例1:

輸入:["a==b","b!=a"]
輸出:false
解釋:如果我們指定,a = 1 且 b = 1,那麼可以滿足第一個方程,但無法滿足第二個方程。沒有辦法分配變量同時滿足這兩個方程。

示例2:

輸出:["b==a","a==b"]
輸入:true
解釋:我們可以指定 a = 1 且 b = 1 以滿足滿足這兩個方程。

示例3:

輸入:["a==b","b==c","a==c"]
輸出:true

示例4:

輸入:["a==b","b!=c","c==a"]
輸出:false

示例5:

輸入:["c==c","b==d","x!=z"]
輸出:true

提示:

1 <= equations.length <= 500
equations[i].length == 4
equations[i][0] 和 equations[i][3] 是小寫字母
equations[i][1] 要麼是 '=',要麼是 '!'
equations[i][2] 是 '='

 昨天又咕咕咕了,u1si這學期才學dijkstra算法,思路簡直秒出,但是復現真的是車禍現場,bug層出不窮,最近的情況還得辦事,每天只給了自己兩小時做題時間,昨天是真沒整出來,埋坑+1。

 思路:等式相等具有傳遞性,一開始想到的是圖,想到昨天的復現瞬間不想做了,後面又覺得可以用並查集,主要思路如下:因爲是26個小寫字母,用長度爲26的數組表示頂點;做兩次遍歷,先掃描所有等式,將等式兩邊的頂點合併成一個集合;再掃描所有的不等式,檢查不等式的兩個頂點是不是在一個集合裏(根節點是否相同),如果在就直接返回 false 。如果所有檢查都沒有矛盾,返回 true。

代碼如下:

class UnionFind{
    int parent[26];
public:
    //初始化
    UnionFind(){
        for(int i = 0; i < 26; ++i)
            parent[i] = i;
    }
    //查找根節點
    int find(int x){
        if(parent[x] == x)
            return parent[x];
        return parent[x] = find(parent[x]);
    }
    //合併
    void merge(int x, int y){
        int a = find(x);
        int b = find(y);
        parent[a] = b;
    }
};


class Solution {
public:
    bool equationsPossible(vector<string>& equations) {
        UnionFind u; 
        
        for(int i=0;i<equations.size();i++){
            if(equations[i][1]=='=') {
                int x=equations[i][0]-'a';
                int y=equations[i][3]-'a';
                if(u.find(x)!=u.find(y)) //二者根節點不同,合併
                   u.merge(x,y);  
            }
        }
        for(int i=0;i<equations.size();i++){
            //取不等式
            if(equations[i][1]=='!') {
                int x=equations[i][0]-'a';
                int y=equations[i][3]-'a';
                if(u.find(x)==u.find(y)) //二者根節點相同說明x=y,不滿足條件故返回false
                    return false;
            }
        }
        return true;
    }
};

運行結果:2020-06-08_095640

 和官方題解是一個思路,但是跑了下代碼發現官方的是8ms,仔細看了看復現發現是類裏邊初始化的時間差,官方用的iota要比循環賦值快,而我這裏用的for遍歷,改了之後我也是8ms了,iota牛逼,又學到一個函數。

改動部分:

    //初始化
    UnionFind(){
        iota(parent, parent+26, 0);
    }

運行結果:

2020-06-08_101910

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