0558. 四叉树交集【中等】
1. 📝 题目描述
二进制矩阵中的所有元素不是 0 就是 1。
给你两个四叉树,quadTree1 和 quadTree2。其中 quadTree1 表示一个 n * n 二进制矩阵,而 quadTree2 表示另一个 n * n 二进制矩阵。
请你返回一个表示 n * n 二进制矩阵的四叉树,它是 quadTree1 和 quadTree2 所表示的两个二进制矩阵进行 按位逻辑或运算 的结果。
注意,当 isLeaf 为 False 时,你可以把 True 或者 False 赋值给节点,两种值都会被判题机制 接受。
四叉树数据结构中,每个内部节点只有四个子节点。此外,每个节点都有两个属性:
val:储存叶子结点所代表的区域的值。1 对应 True,0 对应 False;isLeaf: 当这个节点是一个叶子结点时为 True,如果它有 4 个子节点则为 False。
java
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
我们可以按以下步骤为二维区域构建四叉树:
- 如果当前网格的值相同(即,全为
0或者全为1),将isLeaf设为 True,将val设为网格相应的值,并将四个子节点都设为 Null 然后停止。 - 如果当前网格的值不同,将
isLeaf设为 False, 将val设为任意值,然后如下图所示,将当前网格划分为四个子网格。 - 使用适当的子网格递归每个子节点。

如果你想了解更多关于四叉树的内容,可以参考 百科。
四叉树格式:
输出为使用层序遍历后四叉树的序列化形式,其中 null 表示路径终止符,其下面不存在节点。
它与二叉树的序列化非常相似。唯一的区别是节点以列表形式表示 [isLeaf, val]。
如果 isLeaf 或者 val 的值为 True,则表示它在列表 [isLeaf, val] 中的值为 1 ;如果 isLeaf 或者 val 的值为 False,则表示值为 0。
示例 1:

txt
输入:
quadTree1 = [[0,1],[1,1],[1,1],[1,0],[1,0]],
quadTree2 = [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]
输出:[[0,0],[1,1],[1,1],[1,1],[1,0]]
解释:
quadTree1 和 quadTree2 如上所示。由四叉树所表示的二进制矩阵也已经给出。
如果我们对这两个矩阵进行按位逻辑或运算,则可以得到下面的二进制矩阵,由一个作为结果的四叉树表示。
注意,我们展示的二进制矩阵仅仅是为了更好地说明题意,你无需构造二进制矩阵来获得结果四叉树。1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10

示例 2:
txt
输入:
quadTree1 = [[1,0]],
quadTree2 = [[1,0]]
输出:[[1,0]]
解释:
两个数所表示的矩阵大小都为 1*1,值全为 0
结果矩阵大小为 1*1,值全为 0。1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
提示:
quadTree1和quadTree2都是符合题目要求的四叉树,每个都代表一个n * n的矩阵。n == 2^x,其中0 <= x <= 9.
2. 🎯 s.1 - 递归
c
struct Node* intersect(struct Node* quadTree1, struct Node* quadTree2) {
if (quadTree1->isLeaf) return quadTree1->val ? quadTree1 : quadTree2;
if (quadTree2->isLeaf) return quadTree2->val ? quadTree2 : quadTree1;
struct Node* tl = intersect(quadTree1->topLeft, quadTree2->topLeft);
struct Node* tr = intersect(quadTree1->topRight, quadTree2->topRight);
struct Node* bl = intersect(quadTree1->bottomLeft, quadTree2->bottomLeft);
struct Node* br = intersect(quadTree1->bottomRight, quadTree2->bottomRight);
if (tl->isLeaf && tr->isLeaf && bl->isLeaf && br->isLeaf &&
tl->val == tr->val && tr->val == bl->val && bl->val == br->val) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->val = tl->val;
node->isLeaf = 1;
node->topLeft = node->topRight = node->bottomLeft = node->bottomRight = NULL;
return node;
}
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->val = 0;
node->isLeaf = 0;
node->topLeft = tl;
node->topRight = tr;
node->bottomLeft = bl;
node->bottomRight = br;
return node;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
js
/**
* @param {_Node} quadTree1
* @param {_Node} quadTree2
* @return {_Node}
*/
var intersect = function (quadTree1, quadTree2) {
if (quadTree1.isLeaf) return quadTree1.val ? quadTree1 : quadTree2
if (quadTree2.isLeaf) return quadTree2.val ? quadTree2 : quadTree1
const tl = intersect(quadTree1.topLeft, quadTree2.topLeft)
const tr = intersect(quadTree1.topRight, quadTree2.topRight)
const bl = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft)
const br = intersect(quadTree1.bottomRight, quadTree2.bottomRight)
if (
tl.isLeaf &&
tr.isLeaf &&
bl.isLeaf &&
br.isLeaf &&
tl.val === tr.val &&
tr.val === bl.val &&
bl.val === br.val
) {
return new _Node(tl.val, true)
}
return new _Node(false, false, tl, tr, bl, br)
}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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
py
class Solution:
def intersect(self, quadTree1: 'Node', quadTree2: 'Node') -> 'Node':
if quadTree1.isLeaf:
return quadTree1 if quadTree1.val else quadTree2
if quadTree2.isLeaf:
return quadTree2 if quadTree2.val else quadTree1
tl = self.intersect(quadTree1.topLeft, quadTree2.topLeft)
tr = self.intersect(quadTree1.topRight, quadTree2.topRight)
bl = self.intersect(quadTree1.bottomLeft, quadTree2.bottomLeft)
br = self.intersect(quadTree1.bottomRight, quadTree2.bottomRight)
if tl.isLeaf and tr.isLeaf and bl.isLeaf and br.isLeaf and tl.val == tr.val == bl.val == br.val:
return Node(tl.val, True)
return Node(False, False, tl, tr, bl, br)1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 时间复杂度:
,其中 n 是矩阵的边长 - 空间复杂度:
,递归栈深度
算法思路:
- 若其中一棵树是叶子节点,值为 1 则直接返回该节点,否则返回另一棵树
- 递归合并四个子节点,若四个子节点均为叶子且值相同则合并为一个叶子