【算法训练】并查集

128 阅读2分钟

一、等式方程的可满足性 990

在这里插入图片描述

1、分析

题目中的==,表示的其实是联通;!=表示的是不连通关系。思路就是,先将所有的联通关系都建立起来,然后再遍历!=操作,看是否会破坏相关连通性。若破坏了,证明是不可满足的。 具体见代码和注释。

2、代码

class Solution:
    def equationsPossible(self, equations: List[str]) -> bool:
        # 初始化父节点数组,让每个节点的父节点指针都指向自己
        parent = [i for i in range(0,26)]
        # 寻找根节点,在这个过程中做路径压缩,将联通的节点都连接到同一个根节点上,从而减少树的高度
        def find(p): 
            if parent[p] != p:
                parent[p] = find(parent[p])
            return parent[p]
        # 判断是否联通,就看两个节点的父节点是否是同一个就行(因为我们的find函数,会保证联通的都连接到同一个根节点上)
        def isconnect(p,q):
            rootp = find(p)
            rootq = find(q)
            return rootp==rootq
        # 联通两个节点,寻找各自的父节点,由于不用担心出现不平衡情况,可以任意将其中一个根节点连接在另一个根节点上即可
        def union(p,q):
            rootp = find(p)
            rootq = find(q)
            if rootp==rootq:
                return
            parent[rootp] = rootq

        # 题目中==表达的是联通关系,所以先遍历,构建所有的联通关系。这里将字母映射到0-25(因为总共26个字母),便于操作
        for item in equations:
            a = item[0]
            flag = item[1]
            b = item[3]
            temp= ord('a')
            if flag=='=':
                union(ord(a)-temp,ord(b)-temp)
        # 题目中!=表达的是非联通关系,因此我们遍历不等关系,如果操作数本来是联通的,那么就出现了矛盾,是不满足的,直接返回flase
        for item in equations:
            a = item[0]
            flag = item[1]
            b = item[3]
            temp= ord('a')
            if flag=='!':
                if isconnect(ord(a)-temp,ord(b)-temp):
                    return False
        return True
                

JS

/**
 * @param {string[]} equations
 * @return {boolean}
 */
var equationsPossible = function(equations) {
    let parent = Array(26).fill(0)
    for(let i=0;i<26;i++){
        parent[i] = i;
    }
    var find = (p)=>{
        if(parent[p]!=p){
            parent[p] = find(parent[p]);
        }
        return parent[p];
    }
    var isconnect = (p,q)=>{
        let rootp = find(p);
        let rootq = find(q);
        return rootp===rootq;
    }
    var union = (p,q) => {
        let rootp = find(p);
        let rootq = find(q);
        if(rootp===rootq){
            return 
        }
        parent[rootp]=rootq;
    }
    for(let item of equations){
        let a=item.charCodeAt(0),flag=item[1],b=item.charCodeAt(3);
        let temp = 'a'.charCodeAt();
        if(flag=='='){
            union(a-temp,b-temp);
        }
    }
    for(let item of equations){
        let a=item.charCodeAt(0),flag=item[1],b=item.charCodeAt(3);
        let temp = 'a'.charCodeAt();
        if(flag=='!'){
            if(isconnect(a-temp,b-temp)){
                return false;
            }
        }
    }
    return true;
};