这是悦乐书的第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)的更多相关文章

  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. 使用gson将字符串转换成对象

    Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create(); System.out.pr ...

  2. Django—ajax、前端后端编码格式,bulk_create批量插入语数据库、自定义分页

    一.ajax简介: XML也是一门标记语言该语法应用场景 1.写配置文件 2.可以写前端页面(odoo框架中 erp) 每家公司都会有属于这家公司独有的内部管理软件:专门用来开发企业内部管理软件 框架 ...

  3. Acwing-101-最高的牛(差分)

    链接: https://www.acwing.com/problem/content/103/ 题意: 有 N 头牛站成一行,被编队为1.2.3-N,每头牛的身高都为整数. 当且仅当两头牛中间的牛身高 ...

  4. 将TextEdit设置为密码框

    属性--Properties--UseSystemPasswordChar设置为true

  5. 解决c#distinct不好用的问题

    当一个结合中想根据某一个字段做去重方法时使用以下代码 IQueryable 继承自IEnumerable 先举例: #region linq to object List<People> ...

  6. es6的Map结构

    es6的Map结构主要解决Object的键名只能是单一属性的问题.它可以是字符串,对象,数组,等等 其中有个问题要注意一下,就是 var map = new Map(); map.set(['a'], ...

  7. uniapp动态改变底部tabBar和导航标题navigationBarTitleText

    在开发中,我们会遇到需求国际化,那么底部tabBar和导航标题navigationBarTitleText就要动态切换: 1.改变底部tabBar: uni.setTabBarItem({ index ...

  8. 【leetcode】1250. Check If It Is a Good Array

    题目如下: Given an array nums of positive integers. Your task is to select some subset of nums, multiply ...

  9. CSS 按钮

    总结有关按钮的各种样式 ㈠基本按钮样式 看一下没有进行css样式设计时按钮的样子与进行样式设计的按钮样子 <!DOCTYPE html> <html> <head> ...

  10. jquery pageX属性 语法

    jquery pageX属性 语法 作用:pageX() 属性是鼠标指针的位置,相对于文档的左边缘. 语法:event.page 参数: 参数 描述 event     必需.规定要使用的事件.这个  ...