990. Satisfiability of Equality Equations

990. Satisfiability of Equality Equations

Given an array equations of strings that represent relationships between variables, each string equations[i] has length 4 and takes one of two different forms: “a==b” or “a!=b”. Here, a and b are lowercase letters (not necessarily different) that represent one-letter variable names.

Return true if and only if it is possible to assign integers to variable names so as to satisfy all the given equations.

Example 1:

Input: ["a==b","b!=a"]
Output: false
Explanation: If we assign say, a = 1 and b = 1, then the first equation is satisfied, but not the second.  There is no way to assign the variables to satisfy both equations.

Example 2:

Input: ["b==a","a==b"]
Output: true
Explanation: We could assign a = 1 and b = 1 to satisfy both equations.

Example 3:

Input: ["a==b","b==c","a==c"]
Output: true

Example 4:

Input: ["a==b","b!=c","c==a"]
Output: false

Example 5:

Input: ["c==c","b==d","x!=z"]
Output: true

Note:

1 <= equations.length <= 500
equations[i].length == 4
equations[i][0] and equations[i][3] are lowercase letters
equations[i][1] is either '=' or '!'
equations[i][2] is '='

方法1: Union Find

思路:

因为限定在单个字符,用一个26单位长的向量来记录祖先。第一遍遍历等式,建立所有union。第二遍遍历所有不等式,如果有相同祖先的两个数在这里强制不等,则返回false。否则遍历结束返回true。

易错点:

Example: ["b==b","e==c","e==c","d!=e"]

  1. if (a == b) continue; 要排除在union时 ,也就是第一遍find的时候b == b的情况。这时如果不continue,会出现第二遍find中死循环的情况。因为第一遍union操作中错误的将为自己的祖先指向自己(应该保持-1不变),且一定不为-1,find不会终止。
  2. while (roots[i] ! = -1 && roots[i] ) 如果两个相同等式在union过程中重复出现,此时c和b的祖先都是b,roots[x] = y 会将b指向自己,同理在find中死循环

NOTE: 为了防止这种情况发生,最好都initialize成 roots[i] = i,而判断条件就简化为while (roots[i] != i )

class Solution {
public:
    bool equationsPossible(vector<string>& equations) {
        vector<int> roots(26, -1);
        for (int i = 0; i < 26; i++){
            roots[i] = i;
        }
        
        for (auto eq: equations){
            if (eq[1] == '='){
                int a = int(eq[0] - 'a');  
                int b = int(eq[3] - 'a');
                if (a == b) continue;
                int x = find(roots, a);
                int y = find(roots, b);
               
                roots[x] = y;
            }
        }
        
        // printVector(roots);
        
        
        for (auto eq: equations){
            if (eq[1] == '!'){ 
                int a = int(eq[0] - 'a');
                int b = int(eq[3] - 'a');
                
                int x = find(roots, a);
                int y = find(roots, b);
                if (x == y){
                    return false;
                }
            }
        }
        return true;
    }
    
    int find(vector<int> & roots, int i){
        // while (roots[i] != -1 && roots[i] != i){
        while (roots[i] != i){
            i = roots[i];
        }
        return i;
    }
    
    void printVector(vector<int> & v){
            for (int a : v){
                cout << a << " ";
            }
        cout << endl;
        }
};

discussion的简洁版,原理一样:https://leetcode.com/problems/satisfiability-of-equality-equations/discuss/234486/JavaC%2B%2BPython-Easy-Union-Find

    int uf[26];
    bool equationsPossible(vector<string>& equations) {
        for (int i = 0; i < 26; ++i) uf[i] = i;
        for (string e : equations)
            if (e[1] == '=')
                uf[find(e[0] - 'a')] = find(e[3] - 'a');
        for (string e : equations)
            if (e[1] == '!' && find(e[0] - 'a') == find(e[3] - 'a'))
                return false;
        return true;
    }

    int find(int x) {
        if (x != uf[x]) uf[x] = find(uf[x]);
        return uf[x];
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值