这是悦乐书的第374次更新,第401篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第235题(顺位题号是993)。在二叉树中,根节点在深度0处,并且每个深度为k的节点的子节点,他们深度为k + 1

如果二元树的两个节点具有相同的深度但具有不同的父节点,则它们是堂兄弟。

我们给出了具有唯一值的二叉树root,以及树中两个不同节点的值xy

当且仅当对应于值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 第一种解法

题目的意思是xy在同一层,但是他们的父级节点不一样,也就是xy属于堂兄弟的关系。

使用BFS(广度优先)的算法,通过迭代的方式借助Stack来实现,使用了一个额外的方法,分别求出xy的层级和他们的父级节点,用一个长度为2的数组返回,如果xy的层级相同且父级结点不同,就返回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)的更多相关文章

  1. [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 ...

  2. 二叉树中的最大路径和 · Binary Tree Maximum Path Sum

    [抄题]: 给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和) [思维问题]: 不会写分合法 [一句话思路]: 用两次分治:ro ...

  3. LeetCode 103. 二叉树的锯齿形层次遍历(Binary Tree Zigzag Level Order Traversal)

    103. 二叉树的锯齿形层次遍历 103. Binary Tree Zigzag Level Order Traversal 题目描述 给定一个二叉树,返回其节点值的锯齿形层次遍历.(即先从左往右,再 ...

  4. LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)

    104. 二叉树的最大深度 104. Maximum Depth of Binary Tree 题目描述 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说 ...

  5. LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)

    题目描述 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路 后 ...

  6. LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)

    题目描述 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解题思路 二叉树转化为链表的基本 ...

  7. 【LeetCode】993. Cousins in Binary Tree 解题报告(C++ & python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...

  8. 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 ...

  9. 【Leetcode_easy】993. Cousins in Binary Tree

    problem 993. Cousins in Binary Tree 参考 1. Leetcode_easy_993. Cousins in Binary Tree; 完

随机推荐

  1. Mybatis日志无打印的问题

    添加maven依赖 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j1 ...

  2. 【Linux学习四】Linux下Vim命令操作

    1.Vim介绍 Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性. 第一阶段通过vimtutor的学习,加强vim的熟练度 1.1光标移动 hjkl左 ...

  3. Python 模块 Ⅱ

    搜索路径 当你导入一个模块,Python 解析器对模块位置的搜索顺序是: 1.当前目录 2.如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录. 3.如果都 ...

  4. 信息提示框:MessageBox

    一 函数原型及参数 function MessageBox(hWnd: HWND; Text, Caption: PChar; Type: Word): Integer;   1.参数列表    hW ...

  5. 手动升级 Confluence - 开始升级之前

    在本指南中,我们将会帮助你使用 zip / tar.gz 文件将你的 Confluence 安装实例在 Windows 或者 Linux 版本中升级到最新的版本. 升级到任何最新的版本都是免费的,如果 ...

  6. 3.JSP

        JSP(Java Server Pages)页面是指扩展名为.jsp的文件,在一个JSP中可以包含指令标识,HTML代码, JavaScript代码,嵌入的Java代码,注释和JSP动作标识等 ...

  7. Spring data redis-StringRedisTemplate 用法

    Spring-data-redis为spring-data模块中对redis的支持部分,简称为“SDR”,提供了基于jedis客户端API的高度封装以及与spring容器的整合,事实上jedis客户端 ...

  8. windows 安装使用 Memcached

    Windows无官方版本:下载地址http://static.runoob.com/download/memcached-win64-1.4.4-14.zip 安装: 1.解压下载的压缩包2.命令行模 ...

  9. OkHttp3 使用详解

    一,简介 OkHttp 是一个高效的 HTTP 客户端,具有非常多的优势: 能够高效的执行 http,数据加载速度更快,更省流量 支持 GZIP 压缩,提升速度,节省流量 缓存响应数据,避免了重复的网 ...

  10. 53道java多线程面试题整理及答案(2018年)

    最近看到网上流传着,各种面试经验及面试题,往往都是一大堆技术题目贴上去,而没有答案. 为此我业余时间整理了Java多线程相关的53道常见面试题,及详细答案,你可以用它来好好准备面试.望各路大牛,发现不 ...