DailyChallenge
990. 等式方程的可满足性
Medium
20200608
Description
给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 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 <= equations.length <= 500
- equations[i].length == 4
- equations[i][0] 和 equations[i][3] 是小写字母
- equations[i][1] 要么是 ‘=’,要么是 ‘!’
- equations[i][2] 是 ‘=’
Solution
- Floyd算法构建无向图,提供一个思路吧,虽然时间和空间复杂度都很大。
- 最近周赛,每日一题都是图相关的题目,所以我就往无向图的角度思考
- 先用一个26*26的数组存图
- 遍历equations建立相连的边
- 遍历equations中不等的来证伪
class Solution {
public boolean equationsPossible(String[] equations) {
int len = equations.length;
// 只有一个等式的时候不会建图,所以特例分析
// 注意["a!=a"]这个样例
if(len == 1){
if(equations[0].charAt(0) == equations[0].charAt(3) && equations[0].charAt(1) == '='){
return true;
}else if(equations[0].charAt(0) != equations[0].charAt(3) && equations[0].charAt(1) != '='){
return true;
}else{
return false;
}
}
// 先设为真,因为是通过==的等式建图,在通过!=的方式证伪
boolean res = true;
// 还是要建图
// 都是小写字母,那就用数组的下标来代表字母
// 因为这个可以都用数字来表示,所以用二维数组来比较方便
// 否则像126题单词接龙II那样建图巨麻烦
boolean[][] letters = new boolean [26][26];
// 记录不等的式子的下标
ArrayList<Integer> notEqualId = new ArrayList<>();
for(int i = 0; i < len; i++){
int m = equations[i].charAt(0) - 'a';
int n = equations[i].charAt(3) - 'a';
char sign = equations[i].charAt(1);
if(sign == '='){
// 无向图
letters[m][n] = true;
letters[n][m] = true;
}else{
notEqualId.add(i);
}
}
// Floyd 算法建图
// 这个算法很牛,一定要弄明白k为什么在最外层,可以查查博客
// tips:Floyd算法是动态规划,这个k相当于状态转移相关的值
for(int k = 0; k < 26; k++){
for(int i = 0; i < 26; i++){
for(int j = 0; j < 26; j++){
if(letters[i][k] && letters[k][j]){
letters[i][j] = true;
}
}
}
}
// 遍历不等的,如果不等的两个字母在图中已经相连,就可以返回false
// 注意有equations[id].charAt(0)和equations[id].charAt(3)相等情况
for(int i = 0; i < notEqualId.size(); i++){
int id = notEqualId.get(i);
int m = equations[id].charAt(0) - 'a';
int n = equations[id].charAt(3) - 'a';
// m和n相等的话,不会进判断,因为建图的时候就没有使得对角线相连了
if(letters[m][n] || m == n){
res = false;
}
}
return res;
}
}
- 我的公众号: 每日分享LeetCode, 让你走在路上坐在车上也能看算法题,欢迎大家扫码关注。