[路飞]_等式方程的可满足性

206 阅读2分钟

990. 等式方程的可满足性

题目

给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:"a==b" 或 "a!=b"。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。

只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。

示例1

输入:["a==b","b!=a"]
输出:false
解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。没有办法分配变量同时满足这两个方程。

题解

并查集

  • 构建并查集
  • 第一次枚举,将相同的变量合并,使他们指向同一个节点
  • 第二次枚举,找到不同相同的变量a,b的祖先节点,如果a,b祖先节点一样;返回false

代码

var equationsPossible = function (equations) {
// 构建集合
  const list = Array(26)
    .fill(0)
    .map((v, i) => i);

// 第一次遍历
  for (let i = 0; i < equations.length; i++) {
    const a = equations[i][0];
    const b = equations[i][3];
    const s = equations[i][1];
    // 将相同的数据合并在list中,相同的数据公用一个祖先
    if (s === '=') {
      // 相同,合并
      merge(
        a.charCodeAt() - 'a'.charCodeAt(),
        b.charCodeAt() - 'a'.charCodeAt()
      );
    }
    //console.log('list', list);
  }
// 第二次遍历
  for (let i = 0; i < equations.length; i++) {
    const a = equations[i][0];
    const b = equations[i][3];
    const s = equations[i][1];
    // 如果不同的两个变量
    if (s === '!') {
            //寻在不同变量的祖先节点
      const x = loop(a.charCodeAt() - 'a'.charCodeAt());
      const y = loop(b.charCodeAt() - 'a'.charCodeAt());
      // 如果祖先相同,返回false
      if (x === y) return false;
    }
  }
  return true;


// 并查集中的并,将a并给b
  function merge(a, b) {
    const x = loop(a);
    const y = loop(b);
    list[x] = y;
  }

// 递归查询祖先节点,也可以使用迭代
  function loop(n) {
    if (n === list[n]) return list[n];
    return loop(list[n]);
    // while(n !== list[n]){
    //  list[n] =  list[list[n]]
    //  n = list[n]
    // }
    // return list[n]
  }
};