树
分治
题目描述
二进制矩阵中的所有元素不是 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 。
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
}
我们可以按以下步骤为二维区域构建四叉树:
如果当前网格的值相同(即,全为 0
或者全为 1
),将 isLeaf
设为 True ,将 val
设为网格相应的值,并将四个子节点都设为 Null 然后停止。
如果当前网格的值不同,将 isLeaf
设为 False, 将 val
设为任意值,然后如下图所示,将当前网格划分为四个子网格。
使用适当的子网格递归每个子节点。
如果你想了解更多关于四叉树的内容,可以参考 百科 。
四叉树格式:
输出为使用层序遍历后四叉树的序列化形式,其中 null
表示路径终止符,其下面不存在节点。
它与二叉树的序列化非常相似。唯一的区别是节点以列表形式表示 [isLeaf, val]
。
如果 isLeaf
或者 val
的值为 True ,则表示它在列表 [isLeaf, val]
中的值为 1 ;如果 isLeaf
或者 val
的值为 False ,则表示值为 0 。
示例 1:
输入: 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 如上所示。由四叉树所表示的二进制矩阵也已经给出。
如果我们对这两个矩阵进行按位逻辑或运算,则可以得到下面的二进制矩阵,由一个作为结果的四叉树表示。
注意,我们展示的二进制矩阵仅仅是为了更好地说明题意,你无需构造二进制矩阵来获得结果四叉树。
示例 2:
输入: quadTree1 = [[1,0]]
, quadTree2 = [[1,0]]
输出: [[1,0]]
解释: 两个数所表示的矩阵大小都为 1*1,值全为 0
结果矩阵大小为 1*1,值全为 0 。
提示:
quadTree1
和 quadTree2
都是符合题目要求的四叉树,每个都代表一个 n * n
的矩阵。
n == 2x
,其中 0 <= x <= 9
.
解法
方法一
Python3 Java C++ Go
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 """
# Definition for a QuadTree node.
class Node:
def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):
self.val = val
self.isLeaf = isLeaf
self.topLeft = topLeft
self.topRight = topRight
self.bottomLeft = bottomLeft
self.bottomRight = bottomRight
"""
class Solution :
def intersect ( self , quadTree1 : "Node" , quadTree2 : "Node" ) -> "Node" :
def dfs ( t1 , t2 ):
if t1 . isLeaf and t2 . isLeaf :
return Node ( t1 . val or t2 . val , True )
if t1 . isLeaf :
return t1 if t1 . val else t2
if t2 . isLeaf :
return t2 if t2 . val else t1
res = Node ()
res . topLeft = dfs ( t1 . topLeft , t2 . topLeft )
res . topRight = dfs ( t1 . topRight , t2 . topRight )
res . bottomLeft = dfs ( t1 . bottomLeft , t2 . bottomLeft )
res . bottomRight = dfs ( t1 . bottomRight , t2 . bottomRight )
isLeaf = (
res . topLeft . isLeaf
and res . topRight . isLeaf
and res . bottomLeft . isLeaf
and res . bottomRight . isLeaf
)
sameVal = (
res . topLeft . val
== res . topRight . val
== res . bottomLeft . val
== res . bottomRight . val
)
if isLeaf and sameVal :
res = res . topLeft
return res
return dfs ( quadTree1 , quadTree2 )
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 /*
// Definition for a QuadTree node.
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
public Node() {}
public Node(boolean _val,boolean _isLeaf,Node _topLeft,Node _topRight,Node _bottomLeft,Node
_bottomRight) { val = _val; isLeaf = _isLeaf; topLeft = _topLeft; topRight = _topRight; bottomLeft =
_bottomLeft; bottomRight = _bottomRight;
}
};
*/
class Solution {
public Node intersect ( Node quadTree1 , Node quadTree2 ) {
return dfs ( quadTree1 , quadTree2 );
}
private Node dfs ( Node t1 , Node t2 ) {
if ( t1 . isLeaf && t2 . isLeaf ) {
return new Node ( t1 . val || t2 . val , true );
}
if ( t1 . isLeaf ) {
return t1 . val ? t1 : t2 ;
}
if ( t2 . isLeaf ) {
return t2 . val ? t2 : t1 ;
}
Node res = new Node ();
res . topLeft = dfs ( t1 . topLeft , t2 . topLeft );
res . topRight = dfs ( t1 . topRight , t2 . topRight );
res . bottomLeft = dfs ( t1 . bottomLeft , t2 . bottomLeft );
res . bottomRight = dfs ( t1 . bottomRight , t2 . bottomRight );
boolean isLeaf = res . topLeft . isLeaf && res . topRight . isLeaf && res . bottomLeft . isLeaf
&& res . bottomRight . isLeaf ;
boolean sameVal = res . topLeft . val == res . topRight . val
&& res . topRight . val == res . bottomLeft . val && res . bottomLeft . val == res . bottomRight . val ;
if ( isLeaf && sameVal ) {
res = res . topLeft ;
}
return res ;
}
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 /*
// Definition for a QuadTree node.
class Node {
public:
bool val;
bool isLeaf;
Node* topLeft;
Node* topRight;
Node* bottomLeft;
Node* bottomRight;
Node() {
val = false;
isLeaf = false;
topLeft = NULL;
topRight = NULL;
bottomLeft = NULL;
bottomRight = NULL;
}
Node(bool _val, bool _isLeaf) {
val = _val;
isLeaf = _isLeaf;
topLeft = NULL;
topRight = NULL;
bottomLeft = NULL;
bottomRight = NULL;
}
Node(bool _val, bool _isLeaf, Node* _topLeft, Node* _topRight, Node* _bottomLeft, Node* _bottomRight) {
val = _val;
isLeaf = _isLeaf;
topLeft = _topLeft;
topRight = _topRight;
bottomLeft = _bottomLeft;
bottomRight = _bottomRight;
}
};
*/
class Solution {
public :
Node * intersect ( Node * quadTree1 , Node * quadTree2 ) {
return dfs ( quadTree1 , quadTree2 );
}
Node * dfs ( Node * t1 , Node * t2 ) {
if ( t1 -> isLeaf && t2 -> isLeaf ) return new Node ( t1 -> val || t2 -> val , true );
if ( t1 -> isLeaf ) return t1 -> val ? t1 : t2 ;
if ( t2 -> isLeaf ) return t2 -> val ? t2 : t1 ;
Node * res = new Node ();
res -> topLeft = dfs ( t1 -> topLeft , t2 -> topLeft );
res -> topRight = dfs ( t1 -> topRight , t2 -> topRight );
res -> bottomLeft = dfs ( t1 -> bottomLeft , t2 -> bottomLeft );
res -> bottomRight = dfs ( t1 -> bottomRight , t2 -> bottomRight );
bool isLeaf = res -> topLeft -> isLeaf && res -> topRight -> isLeaf && res -> bottomLeft -> isLeaf && res -> bottomRight -> isLeaf ;
bool sameVal = res -> topLeft -> val == res -> topRight -> val && res -> topRight -> val == res -> bottomLeft -> val && res -> bottomLeft -> val == res -> bottomRight -> val ;
if ( isLeaf && sameVal ) res = res -> topLeft ;
return res ;
}
};
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 /**
* Definition for a QuadTree node.
* type Node struct {
* Val bool
* IsLeaf bool
* TopLeft *Node
* TopRight *Node
* BottomLeft *Node
* BottomRight *Node
* }
*/
func intersect ( quadTree1 * Node , quadTree2 * Node ) * Node {
var dfs func ( * Node , * Node ) * Node
dfs = func ( t1 , t2 * Node ) * Node {
if t1 . IsLeaf && t2 . IsLeaf {
return & Node { Val : t1 . Val || t2 . Val , IsLeaf : true }
}
if t1 . IsLeaf {
if t1 . Val {
return t1
}
return t2
}
if t2 . IsLeaf {
if t2 . Val {
return t2
}
return t1
}
res := & Node {}
res . TopLeft = dfs ( t1 . TopLeft , t2 . TopLeft )
res . TopRight = dfs ( t1 . TopRight , t2 . TopRight )
res . BottomLeft = dfs ( t1 . BottomLeft , t2 . BottomLeft )
res . BottomRight = dfs ( t1 . BottomRight , t2 . BottomRight )
isLeaf := res . TopLeft . IsLeaf && res . TopRight . IsLeaf && res . BottomLeft . IsLeaf && res . BottomRight . IsLeaf
sameVal := res . TopLeft . Val == res . TopRight . Val && res . TopRight . Val == res . BottomLeft . Val && res . BottomLeft . Val == res . BottomRight . Val
if isLeaf && sameVal {
res = res . TopLeft
}
return res
}
return dfs ( quadTree1 , quadTree2 )
}
GitHub