In a binary tree, the root node is at depth 0
, and children of each depth k
node are at depth k+1
.
Two nodes of a binary tree are cousins if they have the same depth, but have different parents.
We are given the root
of a binary tree with unique values, and the values x
and y
of two different nodes in the tree.
Return true
if and only if the nodes corresponding to the values x
and y
are cousins.
Example 1:
Input: root = [1,2,3,4], x = 4, y = 3
Output: false
Example 2:
Input: root = [1,2,3,null,4,null,5], x = 5, y = 4
Output: true
Example 3:
Input: root = [1,2,3,null,4], x = 2, y = 3
Output: false
二叉树的堂兄弟节点。
题意是给一个二叉树和两个节点的值,请判断这两个节点是否是堂兄弟节点。堂兄弟节点的定义是两个节点的深度一样但是两个节点不是来自于同一个父节点。
这道题BFS和DFS都能做,我这里给出两种解法。
既然是BFS,所以做法还是将根节点加入queue然后分别加入左孩子和右孩子,类似树的层序遍历。这里为着判断堂兄弟的关系,我们需要额外判断当前节点的左孩子和右孩子(如果都不为空的话)是不是等于题目给出的另外两个节点值,如果是就要return false。同时,如果X和Y有任何一个节点不存在,也需要return false。只有在X和Y同时存在,但是他们又不共享同一个父亲节点的时候,才能return true。这里写代码的时候有一个细节需要注意,在处理某一层的节点的时候,其实你只能通过上一层的cur.left和cur.right才能判断X和Y的值是否存在,如果存在则说明两者share同一个父亲节点。只有到下一层遍历的时候,通过flag才能知道两者都在同一层但不share同一个父亲节点。
时间O(n)
空间O(n)
Java实现
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public boolean isCousins(TreeNode root, int x, int y) { 18 // corner case 19 if (root == null) { 20 return false; 21 } 22 23 // normal case 24 Queue<TreeNode> queue = new LinkedList<>(); 25 queue.offer(root); 26 while (!queue.isEmpty()) { 27 int size = queue.size(); 28 boolean xflag = false; 29 boolean yflag = false; 30 for (int i = 0; i < size; i++) { 31 TreeNode cur = queue.poll(); 32 if (cur.val == x) { 33 xflag = true; 34 } 35 if (cur.val == y) { 36 yflag = true; 37 } 38 if (cur.left != null && cur.right != null) { 39 if (cur.left.val == x && cur.right.val == y) { 40 return false; 41 } 42 if (cur.left.val == y && cur.right.val == x) { 43 return false; 44 } 45 } 46 if (cur.left != null) { 47 queue.offer(cur.left); 48 } 49 if (cur.right != null) { 50 queue.offer(cur.right); 51 } 52 } 53 if (xflag && yflag) { 54 return true; 55 } 56 } 57 return false; 58 } 59 }
DFS的做法稍微复杂一些。你需要记录几个额外的参数,包括x的父亲节点,y的父亲节点,x的深度,y的深度。判断的依据是当x和y的深度相同但是他们的父亲节点不同的时候,才return true;否则一律return false。DFS的函数也是类似前序遍历的写法。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 TreeNode xparent = null; 3 TreeNode yparent = null; 4 int xdepth = -1; 5 int ydepth = -1; 6 7 public boolean isCousins(TreeNode root, int x, int y) { 8 helper(root, x, y, 0, null); 9 return xdepth == ydepth && xparent != yparent ? true : false; 10 } 11 12 private void helper(TreeNode root, int x, int y, int depth, TreeNode parent) { 13 if (root == null) { 14 return; 15 } 16 if (root.val == x) { 17 xparent = parent; 18 xdepth = depth; 19 } else if (root.val == y) { 20 yparent = parent; 21 ydepth = depth; 22 } 23 helper(root.left, x, y, depth + 1, root); 24 helper(root.right, x, y, depth + 1, root); 25 } 26 }