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; 完
随机推荐
- 本机的IP地址无法打开(Vue项目)
1, 首先找到使用vue脚手架建立项目config文件中的index.js文件2, 修改dev里面的host属性值:改成 host: ‘0.0.0.0’3, 最后在局域网下,使用自己的ip进行连接,同 ...
- 【leetcode】1233. Remove Sub-Folders from the Filesystem
题目如下: Given a list of folders, remove all sub-folders in those folders and return in any order the f ...
- Linux下获得本机IP(非127.0.0.1)
在Linux下用InetAddress.getLocalHost()方法获取本机IP地址,得到的结果总是:127.0.1.1.原来这个是etc/hosts文件中的配置,并非网卡的IP地址. 可用代码如 ...
- C# 3.0
序言 自动实现的属性 匿名类型 查询表达式 Lambda 表达式 从 C# 3 开始,lambda 表达式提供了一种更简洁和富有表现力的方式来创建匿名函数. 使用 => 运算符构造 lambda ...
- HDU 6438 Buy and Resell ( 2018 CCPC 网络赛 && 贪心 )
题目链接 题意 : 给出一些数.你可以从左到右对这些数进行三种操作花费 Ai 买入东西.以 Ai 价格卖出你当前有的东西.或者什么都不做.现在问你可以获取的最大利益是多少? 分析 : 和 CF 867 ...
- max函数结合lambda使用
说明:d.keys() 以及列表可以看做lambda函数的实参,max的判断对象是key的值.最终返回的是使得key的值最大的那个实参.
- js 获取系统时间:年月日 星期 时分秒(动态)
最近再写一个纯html页面,有时间和天气的数据,天气后台给接口,时间要自己获取,我就自己弄了下, <div class="basic"></div> 这是放 ...
- docker删除容器再删除镜像
1. 查询镜像 docker images 现在想删除第一个,ID为 99f85991949f 的镜像. docker rmi ID 从上面看出,需要先停到ID为 67*** 的容器. 2. 查询容 ...
- 客户端框架-MVP
MVP Model-View-Presenter MVP是把MVC中的Controller换成了Presenter(呈现),目的就是为了完全切断View跟Model之间的联系,由Presenter充当 ...
- linux系统基础优化及高级操作命令
Linux基础系统优化 引言没有,只有一张图. Linux的网络功能相当强悍,一时之间我们无法了解所有的网络命令,在配置服务器基础环境时,先了解下网络参数设定命令. ifconfig 查询.设置网卡和 ...