LeetCode.993-二叉树中的堂兄弟(Cousins in Binary Tree)
这是悦乐书的第374次更新,第401篇原创
01 看题和准备
今天介绍的是LeetCode
算法题中Easy
级别的第235
题(顺位题号是993
)。在二叉树中,根节点在深度0处,并且每个深度为k
的节点的子节点,他们深度为k + 1
。
如果二元树的两个节点具有相同的深度但具有不同的父节点,则它们是堂兄弟。
我们给出了具有唯一值的二叉树root
,以及树中两个不同节点的值x
和y
。
当且仅当对应于值x和y的节点是堂兄弟时,才返回true
。例如:
输入:root = [1,2,3,4],x = 4,y = 3
1
/ \
2 3
/
4
输出:false
输入:root = [1,2,3,null,4,null,5],x = 5,y = 4
1
/ \
2 3
\ \
4 5
输出:true
输入:root = [1,2,3,null,4],x = 2,y = 3
1
/ \
2 3
\
4
输出:false
注意:
树中的节点数将介于2和100之间。
每个节点都有一个从1到100的唯一整数值。
02 第一种解法
题目的意思是x
和y
在同一层,但是他们的父级节点不一样,也就是x
和y
属于堂兄弟的关系。
使用BFS(广度优先)的算法,通过迭代的方式借助Stack
来实现,使用了一个额外的方法,分别求出x
和y
的层级和他们的父级节点,用一个长度为2的数组返回,如果x
和y
的层级相同且父级结点不同,就返回true
。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public boolean isCousins(TreeNode root, int x, int y) {
int[] arr = getTreeDepth(root, x);
int[] arr2 = getTreeDepth(root, y);
if (arr.length < 1 || arr2.length < 1) {
return false;
}
return arr[0] != arr2[0] && arr[1] == arr2[1];
}
public int[] getTreeDepth(TreeNode root, int num) {
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
int depth = 0;
while (!stack.isEmpty()) {
Stack<TreeNode> stack2 = new Stack<TreeNode>();
while (!stack.isEmpty()) {
TreeNode tem = stack.pop();
if (tem.left != null) {
// 当前节点的左子节点值等于要找的数
if (tem.left.val == num) {
return new int[] {tem.val, depth+1};
}
stack2.push(tem.left);
}
if (tem.right != null) {
// 当前节点的右子节点值等于要找的数
if (tem.right.val == num) {
return new int[] {tem.val, depth+1};
}
stack2.push(tem.right);
}
}
stack = stack2;
depth++;
}
return new int[] {};
}
03 第二种解法
针对第一种解法,我们也可以将判断的方法融合在一起,依旧是借助栈。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public boolean isCousins2(TreeNode root, int x, int y) {
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while (!stack.isEmpty()) {
Stack<TreeNode> stack2 = new Stack<TreeNode>();
boolean xExist = false, yExist = false;
while (!stack.isEmpty()) {
TreeNode tem = stack.pop();
if (tem.val == x) {
xExist = true;
}
if (tem.val == y) {
yExist = true;
}
// x和y不能有同一个父节点
if (tem.left != null && tem.right != null) {
if (tem.left.val == x && tem.right.val == y) {
return false;
}
if (tem.left.val == y && tem.right.val == x) {
return false;
}
}
if (tem.left != null) {
stack2.push(tem.left);
}
if (tem.right != null) {
stack2.push(tem.right);
}
}
stack = stack2;
if (xExist && yExist) {
return true;
}
}
return false;
}
04 第三种解法
和第二种解法思路一样,只是将栈换成了队列。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public boolean isCousins3(TreeNode root, int x, int y) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
boolean xExist = false, yExist = false;
for (int i=0; i<size; i++) {
TreeNode tem = queue.poll();
if (tem.val == x) {
xExist = true;
}
if (tem.val == y) {
yExist = true;
}
// x和y不能有同一个父节点
if (tem.left != null && tem.right != null) {
if (tem.left.val == x && tem.right.val == y) {
return false;
}
if (tem.left.val == y && tem.right.val == x) {
return false;
}
}
if (tem.left != null) {
queue.offer(tem.left);
}
if (tem.right != null) {
queue.offer(tem.right);
}
}
if (xExist && yExist) {
return true;
}
}
return false;
}
05 第四种解法
借助递归,一个递归方法求深度,一个递归方法找父节点,最后判断深度是否相同且父节点不同。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public boolean isCousins4(TreeNode root, int x, int y) {
return getDepth(root, x, 0) == getDepth(root, y, 0) &&
findParent(root, x) != findParent(root, y);
}
public int getDepth(TreeNode root, int num, int depth){
if (root == null) {
return 0;
}
if (root.val == num) {
return depth;
}
int left = getDepth(root.left, num, depth+1);
int right = getDepth(root.right, num, depth+1);
return Math.max(left, right);
}
public int findParent(TreeNode root, int num) {
if (root == null) {
return 0;
}
if (root.left != null && root.left.val == num) {
return root.val;
}
if (root.right != null && root.right.val == num) {
return root.val;
}
int left = findParent(root.left, num);
int right = findParent(root.right, num);
return Math.max(left, right);
}
06 第五种解法
我们也可以只是用一次递归方法,借助全局变量来解。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
private int depthX;
private int depthY;
private TreeNode parentX;
private TreeNode parentY;
public boolean isCousins5(TreeNode root, int x, int y) {
helper(root, x, y, 0, null);
return depthX == depthY && parentX != parentY;
}
public void helper(TreeNode root, int x, int y, int depth, TreeNode parent) {
if (root == null) {
return ;
}
if (root.val == x) {
depthX = depth;
parentX = parent;
} else if (root.val == y) {
depthY = depth;
parentY = parent;
}
helper(root.left, x, y, depth+1, root);
helper(root.right, x, y, depth+1, root);
}
07 第六种解法
我们还可以将第五种解法中找父节点的变量换成int
类型,因为节点值唯一,可以直接使用节点值参与判断。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
private int depthX;
private int depthY;
private int parentX;
private int parentY;
public boolean isCousins6(TreeNode root, int x, int y) {
helper(root, x, y, 0, 0);
return depthX == depthY && parentX != parentY;
}
public void helper(TreeNode root, int x, int y, int depth, int parent) {
if (root == null) {
return ;
}
if (root.val == x) {
depthX = depth;
parentX = parent;
} else if (root.val == y) {
depthY = depth;
parentY = parent;
}
helper(root.left, x, y, depth+1, root.val);
helper(root.right, x, y, depth+1, root.val);
}
08 小结
算法专题目前已连续日更超过七个月,算法题文章241+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode.993-二叉树中的堂兄弟(Cousins in Binary Tree)的更多相关文章
- [Swift]LeetCode124. 二叉树中的最大路径和 | Binary Tree Maximum Path Sum
Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...
- 二叉树中的最大路径和 · Binary Tree Maximum Path Sum
[抄题]: 给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和) [思维问题]: 不会写分合法 [一句话思路]: 用两次分治:ro ...
- LeetCode 103. 二叉树的锯齿形层次遍历(Binary Tree Zigzag Level Order Traversal)
103. 二叉树的锯齿形层次遍历 103. Binary Tree Zigzag Level Order Traversal 题目描述 给定一个二叉树,返回其节点值的锯齿形层次遍历.(即先从左往右,再 ...
- LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
104. 二叉树的最大深度 104. Maximum Depth of Binary Tree 题目描述 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说 ...
- LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)
题目描述 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 后 ...
- LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
题目描述 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解题思路 二叉树转化为链表的基本 ...
- 【LeetCode】993. Cousins in Binary Tree 解题报告(C++ & python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...
- LeetCode 993. Cousins in Binary Tree(判断结点是否为Cousin)
993. Cousins in Binary Tree In a binary tree, the root node is at depth 0, and children of each dept ...
- 【Leetcode_easy】993. Cousins in Binary Tree
problem 993. Cousins in Binary Tree 参考 1. Leetcode_easy_993. Cousins in Binary Tree; 完
随机推荐
- phpMyAdmin无法缓存模板文件,所以会运行缓慢。
出现这个的原因是 phpmyadmin的安装目录, tmp目录不存在,或者存在但是权限不对.这是个缓存目录,可以加快phpmyadmin的运行,即使不理睬这个警告信息,也不会影响程序的执行. 解决的方 ...
- META标签的设置
㈠定义及用法 ⑴<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. ⑵<meta> 标签位于文档的头部,不 ...
- CSS 的伪元素是什么?
CSS伪元素是用来添加一些选择器的特殊效果.用于:向某个选择器中的文字的首行. ㈠语法 ①伪元素的语法: selector:pseudo-element {property:value;} ②CSS类 ...
- Single-shot Object Detection
以下转自:http://lanbing510.info/2017/08/28/YOLO-SSD.html 在深度学习出现之前,传统的目标检测方法大概分为区域选择(滑窗).特征提取(SIFT.HOG等) ...
- max函数结合lambda使用
说明:d.keys() 以及列表可以看做lambda函数的实参,max的判断对象是key的值.最终返回的是使得key的值最大的那个实参.
- Redis的一点笔记
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 优势: 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s . 丰富 ...
- 「CQOI 2014」危桥
题目链接 戳我 \(Solution\) 首先往返\(n\)次等价于走\(2n\)次. 将 \(a_n*2,b_n*2\); 那么我们直接按原图构图,然后: \((S,a_1,a_n),(S,b_1, ...
- crm 项目的部署
发布CRM你将使用以下软件 nginx uWSGI CentOS7 CRM项目文件 virtualenv supervisor WSGI.uWSGI python web服务器开发使用WSGI协议(W ...
- 一款兼容性较强的H5播放器-Mediaelementjs
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 【转】diamond专题(一)– 简介和快速使用
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...