Keshawn_lu's Blog

Leetcode 990. 等式方程的可满足性

字数统计: 910阅读时长: 3 min
2020/06/08 Share

题目简介:

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

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

示例 1:

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

示例 2:

1
2
3
输出:["b==a","a==b"]
输入:true
解释:我们可以指定 a = 1 且 b = 1 以满足满足这两个方程。

示例 3:

1
2
输入:["a==b","b==c","a==c"]
输出:true

示例 4:

1
2
输入:["a==b","b!=c","c==a"]
输出:false

示例 5:

1
2
输入:["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]'='

思路:

第一次做并查集的题目,看了两篇比较有意思的博客,把并查集初步的搞懂了。

首先有26个字母,在没有等式限制时,它们自成一派,每个字母都是自己门派的掌门人。

当有等式限制时,若两者相等,则说明两个门派需要合并成一个门派,谁是新的掌门人并不重要。

若两者不能相等时,则寻找各自门派的掌门人,若两者的掌门人是一样的,说明不符合题意,返回false即可。

在寻找掌门人时,可以使用路径压缩,简单点来说,若一开始从掌门人到字母一共有好几个阶级,这样子找掌门人时便要一层一层的向上,比较浪费时间。但是我们关心的只有门派掌门人是谁,和你中间的人是谁并没有关系,所以在寻找的过程中,我们可以将过程中遇到的人都直接隶属于掌门麾下,这样子寻找掌门人的速度就快很多了。

大致上就像这样:

tips:

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class Solution {
public:

vector<int> father;

int find(int x){

if(father[x] == x) //父节点就是本身,自己就是掌门
return x; //返回自己即可
else{

//将自己的父节点设为根节点,路径压缩,将自己直属于掌门麾下
father[x] = find(father[x]);
return father[x]; //返回根节点,本派掌门
}
}

bool equationsPossible(vector<string>& equations) {

father.resize(26);

for(int i = 0; i < 26; i++){

father[i] = i; //都先自成一派
}

for(int i = 0; i < equations.size(); i++){

if(equations[i][1] == '='){

//找第一个字母的掌门
int father1 = find(equations[i][0] - 'a');
//找第二个字母的掌门
int father2 = find(equations[i][3] - 'a');

if(father1 != father2){

//掌门不一样,合并成一个门派
father[father1] = father2;
}
}
}

for(int i = 0; i < equations.size(); i++){

if(equations[i][1] == '!'){

//找第一个字母的掌门
int father1 = find(equations[i][0] - 'a');
//找第二个字母的掌门
int father2 = find(equations[i][3] - 'a');

if(father1 == father2) //掌门不能一样
return false;
}
}

return true;

}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: