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

解题分析及思路:

方法:并查集

思路:

此题有两种关系:

  1. a == b,代表ab相等
  2. a !=b ,代表ab不等

此处方程两边的字母可以看作两个节点,中间的==或者!=代表关系,那么:

  1. 如果a == b,那么ab相等,那么ab的父节点应该是同一个
  2. 如果a != b,那么ab不等,那么ab的父节点应该是不相同的

那么问题回归到并查集,通过并查集判断是否满足方程

  1. 当关系不互斥时(即为 ==的情况),将ab合并
  2. 当关系互斥时(即为!=的情况时,可能会出出现),如果ab的父节点不相同,那么ab不等,返回false

所以我们需要需要处理关系为==的方程,然后再考虑关系为!=的方程,然后通过并查集判断是否满足方程

func equationsPossible(equations []string) bool {
	sort.Slice(equations, func(i, j int) bool {
		if equations[i][1] == '!' {
			return false
		}
		return true
	})
	var parent = make([]int, 26)
	for i := 0; i < 26; i++ {
		parent[i] = i
	}
	var find func(int) int
	find = func(x int) int {
		if parent[x] != x {
			parent[x] = find(parent[x])
		}
		return parent[x]
	}
	var union func(int, int)
	union = func(x, y int) {
		parent[find(x)] = find(y)
	}
	for index := range equations {
		left, symbol, right := equations[index][0], equations[index][1], equations[index][3]
		if symbol == '=' {
			union(int(left-'a'), int(right-'a'))
		} else if find(int(left-'a')) == find(int(right-'a')) {
			return false
		}
	}
	return true
}

复杂度:

  • 时间复杂度:O(n + C *log C),其中n为方程个数,C为变量个数
  • 空间复杂度:O(C)

执行结果:

  • 执行耗时:1 ms,击败了40.84 的Go用户
  • 内存消耗:2.4 MB,击败了28.50 的Go用户

通过次数 63K 提交次数 116.6K 通过率 54.1%

Related Posts

1026. 节点与其祖先之间的最大差值

## 题目描述:给定二叉树的根节点 root,找出存在于 不同 节点 A 和 B 之间的最大值 V,其中 V = |A.val - B.val|,且 A 是 B 的祖先。(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)示例 1: ![](/img/leetcode/1026节点与其祖先之间的最大差值/tmp-tre

read more

1038. 从二叉搜索树到更大和树

## 题目描述:给定一个二叉搜索树 root (BST),请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。提醒一下, 二叉搜索树 满足下列约束条件:- 节点的左子树仅包含键 小于 节点键的节点。 - 节点的右子树仅包含键 大于 节点键的节点。 - 左右子树也必须是二叉搜索树。*示例 1:***![](/img/leetcode/

read more

105. 从前序与中序遍历序列构造二叉树

## 题目描述:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。示例 1: ``` 输入: preorder = [3,9,20,15,7], inorder = [

read more

106. 从中序与后序遍历序列构造二叉树

## 题目描述:给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。示例 1: ``` 输入:inorder = [9,3,15,20,7], postorder

read more

109. 有序链表转换二叉搜索树

## 题目描述:给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 1。示例 1: ``` 输入: head = [-10,-3,0,5,9] 输出: [0,-3,9

read more

114. 二叉树展开为链表

## 题目描述:给你二叉树的根结点 root ,请你将它展开为一个单链表:- 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。 - 展开后的单链表应该与二叉树 先序遍历 顺序相同。示例 1: ``` 输入:root

read more