[路飞]_一起刷leetcode 990. 等式方程的可满足性

大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。

题目

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. 1 <= equations.length <= 500
  2. equations[i].length == 4
  3. equations[i][0] 和 equations[i][3] 是小写字母
  4. equations[i][1] 要么是 '=',要么是 '!'
  5. equations[i][2] 是 '='

思路

这道题目是一道典型的并查集题目,如果还不清楚什么是并查集的可以先看一下我这篇文章:js中的并查集

  1. 这道题目的考点比较简单,等式方程是否成立我们只需要把不等于的判断一下是否满足即可,如果全是等于的直接返回true即可;
  2. 先通过一轮遍历,把所有相等的值的关联关系全部建立起来;
  3. 再通过一轮遍历,判断所有不等于的元素,等式左右两边的值是否在同一关联关系中即可。

实现

/**
 * @param {string[]} equations
 * @return {boolean}
 */
var equationsPossible = function(equations) {
    const n = equations.length;
    const uf = new UnionFind(26);

    // 把所有相等的建立关联关系
    for (let i = 0; i < n; i++) {
        let [ a, b, c, d ] = equations[i];
        if (b === "=") {
            let index1 = a.charCodeAt() - 'a'.charCodeAt();
            let index2 = d.charCodeAt() - 'a'.charCodeAt();
            uf.merge(index1, index2);
        }
    }

    // 判断所有不相等的是否存在关联关系
    for (let i = 0; i < n; i++) {
        let [ a, b, c, d ] = equations[i];
        if (b === "!") {
            let index1 = a.charCodeAt() - 'a'.charCodeAt();
            let index2 = d.charCodeAt() - 'a'.charCodeAt();
            if (uf.find(index1) === uf.find(index2)) {
                return false;
            }
        }
    }

    return true;
};

class UnionFind {
  constructor(n) {
    // 一开始每个元素关联的都是它们自己, 我们同个索引来标识
    this.parent = new Array(n).fill(0).map((item, index) => index);
  }

  // 找到某个元素的关联者
  find(index) {
    return this.parent[index] = this.parent[index] === index ? index : this.find(this.parent[index]);
  }

  // 建立关联关系
  merge(index1, index2) {
    this.parent[this.find(index2)] = this.find(index1);
  }
}
复制代码

优化思路: 这里可以在第一轮遍历的时候把不相等的元素过滤出来,第二轮遍历直接遍历不相等的元素即可,不过这一步要不会更改原数组,要不就需要开辟额外空间,可以结合具体场景来决定是否优化。

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。

猜你喜欢

转载自juejin.im/post/7048589203566755847
今日推荐