leetcode:993. 二叉树的堂兄弟节点
题目
在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。
如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。
我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。
只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。
示例 1:![[简单] 993. 二叉树的堂兄弟节点 - 图1](/uploads/projects/liangduo-rjrcs@ggu4wq/e2621a089c43756d6af97ce7e282f5dd.png)
输入:root = [1,2,3,4], x = 4, y = 3输出:false
示例 2:![[简单] 993. 二叉树的堂兄弟节点 - 图2](/uploads/projects/liangduo-rjrcs@ggu4wq/347321a8f2e6a10adbe5dc23a51708b5.png)
输入:root = [1,2,3,null,4,null,5], x = 5, y = 4输出:true
示例 3:![[简单] 993. 二叉树的堂兄弟节点 - 图3](/uploads/projects/liangduo-rjrcs@ggu4wq/7aa42170967ea4ce7ac7ef7216919e51.png)
输入:root = [1,2,3,null,4], x = 2, y = 3输出:false
解答 & 代码
解法一:层序遍历
层序遍历的过程中:
- 如果当前节点的两个孩子节点的值分别为 x 和 y,则直接返回 false,因为是亲兄弟节点而不是堂兄弟节点
- 如果一层中同时出现了值为 x 和 y 的节点,则直接返回 true(上面这一条规则已经过滤掉了亲兄弟的情况)
如果遍历结束,则返回 false,说明没有在同一层中同时找到 x 和 y,两者不是堂兄弟
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/class Solution {public:// 层序遍历bool isCousins(TreeNode* root, int x, int y) {if(root == nullptr)return false;queue<TreeNode*> nodeQ;nodeQ.push(root);while(!nodeQ.empty()){bool hasX = false; // 当前层是否包含值为 x 的节点bool hasY = false; // 当前层是否包含值为 y 的节点int levelSize = nodeQ.size();for(int i = 0; i < levelSize; ++i){TreeNode* cur = nodeQ.front();nodeQ.pop();if(cur->val == x)hasX = true;if(cur->val == y)hasY = true;if(cur->left != nullptr)nodeQ.push(cur->left);if(cur->right != nullptr)nodeQ.push(cur->right);// 1. 如果当前节点的左右孩子的值分别为 x、y,则是亲兄弟节点,直接返回 falseif(cur->left != nullptr && cur->right != nullptr &&((cur->left->val == x && cur->right->val == y) ||(cur->left->val == y && cur->right->val == x)))return false;}// 2. 如果同一层中同时包含值为 x 和 y 的节点,则直接返回 true,是堂兄弟节点if(hasX && hasY)return true;}return false; // 3. 遍历结束,x、y 不在同一层,不是堂兄弟}};
复杂度分析:设二叉树节点数为 n
- 时间复杂度 O(n):最坏情况下,遍历二叉树所有节点
- 空间复杂度 O(n):队列 nodeQ 的时间复杂度
执行结果:
执行结果:通过执行用时:4 ms, 在所有 C++ 提交中击败了 56.59% 的用户内存消耗:10.8 MB, 在所有 C++ 提交中击败了 26.58% 的用户
解法二:DFS
DFS 分别找到 x 和 y 的父节点、深度,如果父节点不同、深度相同,则返回 true,否则返回 false
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/class Solution {private:// DFS 寻找值为 x 的节点的深度及其父节点指针,分别存到 xDepth 和 xParentbool dfs(TreeNode* root, int x, int depth, TreeNode*& xParent, int& xDepth){if(root == nullptr)return false;if((root->left != nullptr && root->left->val == x) ||(root->right != nullptr && root->right->val == x)){xParent = root;xDepth = depth + 1;return true;}return dfs(root->left, x, depth + 1, xParent, xDepth) ||dfs(root->right, x, depth + 1, xParent, xDepth);}public:bool isCousins(TreeNode* root, int x, int y) {TreeNode* xParent = nullptr;TreeNode* yParent = nullptr;int xDepth = 0;int yDepth = 0;// 分别找到值为 x、y 的节点的父节点、深度bool findX = dfs(root, x, 0, xParent, xDepth);bool findY = dfs(root, y, 0, yParent, yDepth);// 如果 x、y 节点的父节点不同、深度相同,则返回 true,否则返回 falsereturn findX && findY && xParent != yParent && xDepth == yDepth;}};
复杂度分析:设二叉树节点数为 n
- 时间复杂度 O(n):最坏情况下,遍历二叉树所有节点
- 空间复杂度 O(log n):递归站深度 ~ 二叉树深度
执行结果:
执行结果:通过执行用时:4 ms, 在所有 C++ 提交中击败了 56.59% 的用户内存消耗:10.8 MB, 在所有 C++ 提交中击败了 39.42% 的用户
