首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >并查集-990.等式方程的可满足性-力扣(LeetCode)

并查集-990.等式方程的可满足性-力扣(LeetCode)

作者头像
白天的黑夜
发布2025-10-22 17:32:17
发布2025-10-22 17:32:17
3500
代码可运行
举报
运行总次数:0
代码可运行

个人主页1白天的黑夜1-CSDN博客

专栏:力扣刷题录_1白天的黑夜1的博客-CSDN博客企鹅程序员:Linux 系统与网络编程_1白天的黑夜1的博客-CSDN博客

一、题目解析

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]'='

二、算法原理

对并查集陌生的读者,可以移步另一篇博客学习或者回顾一下

高阶数据结构-并查集-CSDN博客

我们可以看到题目中的一句话,“只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false ”。这些相同的变量也就可以合并为同一个集合,而不相等的不属于通过一个集合。

解法1:自己造轮子(并查集)

我们可以注意到其中变量名只有小写字母,所以我们可以只开26大小的父指针数组,通过将字符-'a'映射到对应位置

具体步骤:
1、粘贴写好的并查集,并通过UnionFindSet()构造函数创建一个大小为26的数组
2、通过分析样例存在==和!=,先处理==
2.1、因为长度固定为4,所以可通过迭代器访问下标为1的字符,如果是'=',则可以合并等式两边下标为0和下标为3的字符
2.2、再次遍历,如果是'!',则判断等式两边字符是否在同一集合,如果在同一集合,则违背要求,所以可以直接返回false
3、如果第二次遍历后,没有违背属于同一集合的要求,则可以返回true

上面的2.2和2.3要注意下标的映射

解法2:lambda表达式

和解法1差不多,就是把并查集的找根函数用lambda表达式实现了。

具体步骤:
1、创建一个大小为26的vector并全部初始化为-1
2、先对下标为1,字符是'='的表达式处理,将表达式两边的字符合并为同一集合
3、再次遍历,对下标为1,字符是'!'的表达式处理,判断表达式两边的字符是否属于同一集合,如果属于同一集合,则违背!=要求,所以返回false
4、最后直接返回true

结合算法原理或者自己的想法,先去敲一敲,试一试,提升自己的代码能力

990. 等式方程的可满足性 - 力扣(LeetCode)

三、代码示例

解法1:

代码语言:javascript
代码运行次数:0
运行
复制
class UnionFindSet
{
public:
	UnionFindSet(size_t n)
		:_ufs(n, -1)
	{ }

	void Union(int x1,int x2)//并
	{
		int root1 = FindRoot(x1);
		int root2 = FindRoot(x2);
		//属于同一个集合没必要合并
		if(root1 == root2) return;

		//小的做根
		if (root1 > root2) swap(root1, root2);

		_ufs[root1] += _ufs[root2];
		_ufs[root2] = root1;
		
	}

	int FindRoot(int x)//找根
	{
		int parent = x;
		while (_ufs[parent] >= 0)
		{
			parent = _ufs[parent];
		}

		return parent;
	}

	bool InSet(int x1,int x2)
	{ 
		return FindRoot(x1) == FindRoot(x2);
	}

	size_t SetSize()
	{
		size_t size = 0;
		for (size_t i = 0; i < _ufs.size(); i++)
		{
			if (_ufs[i] < 0) ++size;
		}

		return size;
	}

private:
	vector<int> _ufs;
};
    //解法1:造轮子
    bool equationsPossible(vector<string>& equations)
    {
        UnionFindSet ufs(26);
        //相等的放在同一个集合中
        for(auto& str : equations)
        {
            if(str[1] == '=')
            {
                ufs.Union(str[0]-'a',str[3]-'a');
            }
        }
        //判断不等的在不在一个集合中
        for(auto& str : equations)
        {
            if(str[1] == '!')
            {
                if(ufs.InSet(str[0]-'a',str[3]-'a'))
                    return false;
            }
        }
        return true;
    }

解法2:

代码语言:javascript
代码运行次数:0
运行
复制
 //解法2;lambda表达式
    bool equationsPossible(vector<string>& equations)
    {
        vector<int> ufs(26,-1);
        auto findRoot = [&ufs](int x)
        {
            while(ufs[x]>=0) x = ufs[x];

            return x;
        };

        //第一先把相等的值加到一个集合中
        for(auto& str : equations)
        {
            if(str[1] == '=')
            {
                int root1 = findRoot(str[0]-'a');
                int root2 = findRoot(str[3]-'a');
                if(root1 != root2)
                {
                    ufs[root1] += ufs[root2];
                    ufs[root2] = root1;
                }
            }
        }

         //第二看不相等的在不在一个集合,在就矛盾了
        for(auto& str : equations)
        {
            if(str[1] == '!')
            {
                int root1 = findRoot(str[0]-'a');
                int root2 = findRoot(str[3]-'a');
                if(root1 == root2)
                {
                   return false;
                }
            }
        }

        return true;
    }

看到最后,如果对您有所帮助,还请点赞、收藏和关注一键三连,在未来还会继续带来优秀的内容,感谢观看,我们下期再见!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目解析
    • 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] 是 '='
  • 二、算法原理
    • 解法1:自己造轮子(并查集)
      • 具体步骤:
      • 1、粘贴写好的并查集,并通过UnionFindSet()构造函数创建一个大小为26的数组
      • 2、通过分析样例存在==和!=,先处理==
      • 3、如果第二次遍历后,没有违背属于同一集合的要求,则可以返回true
    • 解法2:lambda表达式
      • 具体步骤:
      • 1、创建一个大小为26的vector并全部初始化为-1
      • 2、先对下标为1,字符是'='的表达式处理,将表达式两边的字符合并为同一集合
      • 3、再次遍历,对下标为1,字符是'!'的表达式处理,判断表达式两边的字符是否属于同一集合,如果属于同一集合,则违背!=要求,所以返回false
      • 4、最后直接返回true
    • 结合算法原理或者自己的想法,先去敲一敲,试一试,提升自己的代码能力
  • 三、代码示例
    • 解法1:
    • 解法2:
    • 看到最后,如果对您有所帮助,还请点赞、收藏和关注一键三连,在未来还会继续带来优秀的内容,感谢观看,我们下期再见!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档