二叉树 广度优先搜索 树 深度优先搜索
题目描述 给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target。
其中,克隆树 cloned 是原始树 original 的一个 副本 。
请找出在树 cloned 中,与 target 相同 的节点,并返回对该节点的引用(在 C/C++ 等有指针的语言中返回 节点指针,其他语言返回节点本身)。
注意: 你 不能 对两棵二叉树,以及 target 节点进行更改。只能 返回对克隆树 cloned 中已有的节点的引用。
示例 1:
输入: tree = [7,4,3,null,null,6,19], target = 3
输出: 3
解释: 上图画出了树 original 和 cloned。target 节点在树 original 中,用绿色标记。答案是树 cloned 中的黄颜色的节点(其他示例类似)。 示例 2:
输入: tree = [7], target = 7
输出: 7
示例 3:
输入: tree = [8,null,6,null,5,null,4,null,3,null,2,null,1], target = 4
输出: 4
提示:
树中节点的数量范围为 [1, 104 ] 。 同一棵树中,没有值相同的节点。 target 节点是树 original 中的一个节点,并且不会是 null 。
进阶: 如果树中允许出现值相同的节点,将如何解答?
解法 方法一:DFS 思考
在结构相同的克隆树上找到与 \(\textit{target}\) 对应的节点。节点值可以用来对照,但进阶允许重复值,故不能只比数值。两棵树同步 DFS,在原树走到 \(\textit{target}\) 时返回克隆树上的同位节点。
我们设计一个函数 \(dfs(root1, root2)\) ,它会在树 \(root1\) 和 \(root2\) 中同时进行 DFS 遍历,当遍历到某个节点时,如果这个节点恰好为 \(target\) ,那么我们就返回 \(root2\) 中对应的节点。否则,我们递归地在 \(root1\) 和 \(root2\) 的左右子树中寻找 \(target\) ,并返回找到的结果中不为空的那一个。
时间复杂度 \(O(n)\) ,空间复杂度 \(O(n)\) 。其中 \(n\) 是树中节点的数量。
Python3 Java C++ TypeScript C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution :
def getTargetCopy (
self , original : TreeNode , cloned : TreeNode , target : TreeNode
) -> TreeNode :
def dfs ( root1 : TreeNode , root2 : TreeNode ) -> TreeNode :
if root1 is None :
return None
if root1 == target :
return root2
return dfs ( root1 . left , root2 . left ) or dfs ( root1 . right , root2 . right )
return dfs ( original , cloned )
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 /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private TreeNode target ;
public final TreeNode getTargetCopy (
final TreeNode original , final TreeNode cloned , final TreeNode target ) {
this . target = target ;
return dfs ( original , cloned );
}
private TreeNode dfs ( TreeNode root1 , TreeNode root2 ) {
if ( root1 == null ) {
return null ;
}
if ( root1 == target ) {
return root2 ;
}
TreeNode res = dfs ( root1 . left , root2 . left );
return res == null ? dfs ( root1 . right , root2 . right ) : 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 /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public :
TreeNode * getTargetCopy ( TreeNode * original , TreeNode * cloned , TreeNode * target ) {
function < TreeNode * ( TreeNode * , TreeNode * ) > dfs = [ & ]( TreeNode * root1 , TreeNode * root2 ) -> TreeNode * {
if ( root1 == nullptr ) {
return nullptr ;
}
if ( root1 == target ) {
return root2 ;
}
TreeNode * left = dfs ( root1 -> left , root2 -> left );
return left == nullptr ? dfs ( root1 -> right , root2 -> right ) : left ;
};
return dfs ( original , cloned );
}
};
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 /**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function getTargetCopy (
original : TreeNode | null ,
cloned : TreeNode | null ,
target : TreeNode | null ,
) : TreeNode | null {
const dfs = ( root1 : TreeNode | null , root2 : TreeNode | null ) : TreeNode | null => {
if ( ! root1 ) {
return null ;
}
if ( root1 === target ) {
return root2 ;
}
return dfs ( root1 . left , root2 . left ) || dfs ( root1 . right , root2 . right );
};
return dfs ( original , cloned );
}
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 /**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution {
private TreeNode target ;
public TreeNode GetTargetCopy ( TreeNode original , TreeNode cloned , TreeNode target ) {
this . target = target ;
return dfs ( original , cloned );
}
private TreeNode dfs ( TreeNode original , TreeNode cloned ) {
if ( original == null ) {
return null ;
}
if ( original == target ) {
return cloned ;
}
TreeNode left = dfs ( original . left , cloned . left );
return left == null ? dfs ( original . right , cloned . right ) : left ;
}
}