leetcode 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 <= equations.length <= 500
- equations[i].length == 4
- equations[i][0] 和 equations[i][3] 是小写字母
- equations[i][1] 要么是 ‘=’,要么是 ‘!’
- equations[i][2] 是 ‘=’
我的代码
class Solution {
public:
bool equationsPossible(vector<string>& equations) {
vector<set<char>> elements;
for (const auto &equation: equations) {
if (equation[1] == '=') {
bool isExist = false;
for (auto & element : elements) {
if ((element.count(equation[0])) || (element.count(equation[3]))) {
element.insert(equation[0]), element.insert(equation[3]);
isExist = true;
break;
}
}
if (!isExist) {
elements.push_back(set<char>{equation[0], equation[3]});
}
}
}
int num = elements.size();
for (int i = 0; i < num; ++i) {
for (int j = i + 1; j < num; ++j) {
auto temp = elements[i];
temp.insert(elements[j].begin(), elements[j].end());
if (temp.size() < elements[i].size() + elements[j].size()) {
elements[i] = temp;
swap(elements[j], elements[num - 1]);
num -= 1;
i = 0, j = 0;
}
}
}
for (const auto &equation: equations) {
if (equation[1] == '!') {
if (equation[0] == equation[3]) {
return false;
}
for (int i = 0; i < num; ++i) {
if (elements[i].count(equation[0]) && elements[i].count(equation[3])) {
return false;
}
}
}
}
return true;
}
};
我的成绩
执行结果:通过
执行用时 : 16 ms, 在所有 C++ 提交中击败了25.68%的用户
内存消耗 : 12.3 MB, 在所有 C++ 提交中击败了50.00%的用户
一些想法
本道题我的想法是使用一个 vector<set<char>>来记录相等的元素对,然后整合Vector中的set,再遍历不相等的字符串的集合,查看是否同时存在某一个set中,如果存在,则返回false。
执行用时为 0 ms 的范例
class Solution {
public:
int father[26];
bool equationsPossible(vector<string>& equations) {
//并查集
//等于,则都应属于同一个集合,把等于两边的都放一个集合
//然后看不等于两边的元素,是不是出现在同一个集合,如果有在一个集合的就是false
if(equations.empty()) return true;
//if(equations.size()==1) return true;
//父亲先指向自己
for(int i=0;i<26;i++){
father[i] = i;
}
for(int i=0;i<equations.size();i++){
if(equations[i][1]=='='){//等于,合并集合
int fa1 = find(equations[i][0]-'a');
int fa2 = find(equations[i][3]-'a');
if(fa1!=fa2) father[fa1] = fa2;
}
}
for(int i=0;i<equations.size();i++){
if(equations[i][1]=='!'){
int fa1 = find(equations[i][0]-'a');
int fa2 = find(equations[i][3]-'a');
if(fa1==fa2) return false;
}
}
return true;
}
//找跟节点
int find(int i){
//int fa = i;
while(i!=father[i]){
father[i] = father[father[i]];//顺便就路径压缩了
i = father[i];
}
return i;
}
};
思考
我太菜了,没看懂范例。。。,有兴趣可以查看官方题解。