993. 二叉树的堂兄弟节点

本文介绍了一种方法来确定二叉树中两个节点是否为堂兄弟节点。通过深度优先搜索(DFS)或广度优先搜索(BFS),记录节点的深度及父节点,最终比较两节点的深度和父节点来得出结论。
2021-05-17 LeetCode每日一题

链接:https://leetcode-cn.com/problems/cousins-in-binary-tree/

标签:树、深度优先搜索、广度优先搜索

题目

在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。

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

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

只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。

在这里插入图片描述

输入:root = [1,2,3,4], x = 4, y = 3
输出:false

在这里插入图片描述

输入:root = [1,2,3,null,4,null,5], x = 5, y = 4
输出:true

在这里插入图片描述

输入:root = [1,2,3,null,4], x = 2, y = 3
输出:false
  • 二叉树的节点数介于 2100 之间。
  • 每个节点的值都是唯一的、范围为 1100 的整数。

分析

这题可以使用BFS或者DFS来解决。思路就是循环然后记录x和y的深度以及它们对应的父节点,然后就进行比较即可。

BFS解法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        if (root.val == x || root.val == y) {
            return false;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depthX = 0, depthY = 0, fatherX = 0, fatherY = 0, level = -1;

        while (!queue.isEmpty()) {
            int len = queue.size();
            level++;
            for (int i = 0; i < len; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                    if (node.left.val == x) {
                        depthX = level + 1;
                        fatherX = node.val;
                    }
                    if (node.left.val == y) {
                        depthY = level + 1;
                        fatherY = node.val;
                    }
                }
                if (node.right != null) {
                    queue.offer(node.right);
                    if (node.right.val == x) {
                        depthX = level + 1;
                        fatherX = node.val;
                    }
                    if (node.right.val == y) {
                        depthY = level + 1;
                        fatherY = node.val;
                    }
                }

                if (depthX != 0 && depthY != 0) {
                    break;
                }
            }
        }

        if (depthX == depthY && fatherX != fatherY) {
            return true;
        }

        return false;
    }
}

时间复杂度O(n),空间复杂度O(n)

在这里插入图片描述
DFS解法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int parentX = 0, parentY = 0, depthX = 0, depthY = 0;
    public boolean isCousins(TreeNode root, int x, int y) {
        dfs(root.left, x, y, 1, root.val);
        dfs(root.right, x, y, 1, root.val);

        return (parentX != parentY) && (depthX == depthY);
    }

    private void dfs(TreeNode node, int x, int y, int depth, int parent) {
        if (node == null) {
            return;
        }

        if (node.val == x) {
            parentX = parent;
            depthX = depth;
        } else if (node.val == y) {
            parentY = parent;
            depthY = depth;
        } else {
            dfs(node.left, x, y, depth + 1, node.val);
            dfs(node.right, x, y, depth + 1, node.val);
        }
    }
}

时间复杂度O(n),空间复杂度O(1)

在这里插入图片描述

<think>好的,我现在需要解决的问题是:在搜索二叉树(即二叉搜索树,BST)中,堂兄弟节点是否有序。首先,我需要明确几个概念:什么是搜索二叉树?什么是堂兄弟节点?然后分析它们的特性,进而判断堂兄弟节点之间是否存在某种顺序关系。 首先,二叉搜索树的定义是每个节点的左子树中的所有节点都小于该节点,右子树中的所有节点都大于该节点。这个特性保证了BST的中序遍历是有序的。因此,BST的结构对于节点之间的层级关系有严格的规定,但仅限于父子节点和左右子树的相对位置。 接下来,堂兄弟节点的定义是:在同一层(即深度相同)但父节点不同的两个节点。例如,根节点的左右子节点各自的孩子互为堂兄弟。例如,在以下树结构中: ``` A / \ B C / \ / \ D E F G ``` 这里,节点D、E、F、G都是同一层的堂兄弟,而B和C是第一层的兄弟节点,不是堂兄弟堂兄弟节点需要满足同一深度且不同父节点。 现在的问题是,在BST中,堂兄弟节点之间是否保持某种顺序关系?比如,左边的堂兄弟是否一定小于右边的堂兄弟,或者是否存在某种有序性? 根据BST的性质,每个节点的左子树都小于该节点,右子树都大于该节点。但这仅适用于直接父子关系,而堂兄弟节点属于不同的子树分支,它们的父节点不同,可能处于不同的左右分支。例如,根节点A的左孩子B的右孩子E,和根节点A的右孩子C的左孩子F,这两个节点E和F是堂兄弟。此时,E位于左子树分支,F位于右子树分支,根据BST的规则,E应该小于A,F应该大于A,因此E < A < F,所以E < F。这种情况下,左边的堂兄弟E确实小于右边的堂兄弟F。 但是,是否所有情况都是如此呢?需要考虑不同的结构。比如,在更深的层级中,可能存在不同的情况。例如: ``` 5 / \ 3 8 / \ / \ 2 4 6 9 / \ 1 7 ``` 这里,节点1和7的父节点分别是2和6,它们处于同一层(第四层),且父节点不同,因此是堂兄弟。根据BST的结构,节点1位于左子树的最左端,而7位于右子树的右子树的左端。根据BST的性质,1 < 3 < 5 < 6 < 7 < 8 < 9,所以1 < 7,左边的堂兄弟小于右边的堂兄弟。 但是,如果树的结构不同,是否有可能出现堂兄弟节点无序的情况?例如,构造一个BST,其中某一层的堂兄弟节点顺序不一致。例如: ``` 5 / \ 2 8 / \ / \ 1 4 6 9 / \ 3 5 ``` 这里可能存在重复的(如第二个5),但BST不允许重复,所以可能需要调整。或者更复杂的结构: 考虑一个BST: ``` 10 / \ 5 15 / \ / \ 3 7 12 18 / \ / \ 2 4 6 8 ``` 同一层中的堂兄弟节点可能有不同父节点。例如,在第三层,节点3和7的子节点是2、4、6、8。其中,节点2(父节点3)和节点6(父节点7)是堂兄弟,处于同一层(第四层)。根据BST的性质,2 < 3 < 5 < 6 < 7 < 8 < 10 < 12 < 15 < 18,所以2 < 6。同样,左边的堂兄弟小于右边的堂兄弟。 似乎在这种情况下,同一层的堂兄弟节点根据其在树中的位置,左边的堂兄弟节点较小,右边的较大。这是否总是成立? 需要分析BST的结构。在BST中,左子树的所有节点都小于根,右子树的所有节点都大于根。当两个节点堂兄弟时,它们属于不同的子树分支,即它们的父节点分别属于根节点的左子树和右子树,或者在同一子树内的不同分支。例如,父节点都是根左子树的左右子节点,那么它们的子节点作为堂兄弟,是否也遵循左小右大的规则? 比如,考虑根左子树中的情况: ``` 10 / 5 / \ 3 7 / \ / \ 2 4 6 8 ``` 这里,节点2(父3)和节点6(父7)是堂兄弟。3 < 5 < 7,因此2 < 3 < 5 < 6 < 7,所以2 < 6。同样,同一父下的左右子节点,左小右大,但堂兄弟的情况是否也遵循? 可能的关键点在于,堂兄弟节点的父节点在树中的相对位置决定了他们的顺序。例如,如果两个堂兄弟节点的父节点分别是父A和父B,且父A在父B的左边,那么父A的 < 父B的。根据BST的性质,父A的所有后代都小于父A,而父B的所有后代都大于父B。因此,父A的右子节点的最大可能小于父B的左子节点的最小。因此,堂兄弟节点中,父A的后代可能整体小于父B的后代,因此堂兄弟节点可能是有序的。 例如,父A(3)在父B(7)的左边,父A的3 < 父B的7。父A的右子节点4 < 父A(3)? 不对,这里可能有错误。因为父A是3,其右子节点是4,应大于父A。父B是7,其左子节点6应小于7。此时,父A的右子节点4和父B的左子节点6,4 < 6,符合父A < 父B,因此堂兄弟节点4和6的满足4 < 6。 因此,可能堂兄弟节点在BST中是有序的,即左边的堂兄弟小于右边的堂兄弟。但需要验证是否存在反例。 考虑一个更复杂的例子: ``` 20 / \ 10 30 / \ / \ 5 15 25 35 / \ / \ 2 7 12 17 ``` 第三层的堂兄弟节点比如2(父5)、7(父5)、12(父15)、17(父15)。同一层的堂兄弟节点中,左边的堂兄弟(2、7)属于父节点5(在左子树),而右边的堂兄弟(12、17)属于父节点15(在左子树的右子树)。此时,父节点5 < 父节点15,因此父节点的左子树中的后代(如7)是否一定小于父节点15的左子树中的后代(如12)? 根据BST的性质,父节点5的右子节点7应大于5,而父节点15的左子节点12应小于15。由于父节点5 < 父节点15,而7 < 15,所以7 < 12。同样,父节点5的左子节点2 < 5 < 15的左子节点12。因此,所有父节点左边的堂兄弟节点都小于父节点右边的堂兄弟节点。 但如果父节点在同一子树中,比如同为根左子树的两个子节点,例如父节点5和父节点15(父节点10的左右子节点),那么它们的子节点是否有序? 比如,父节点5的右子节点7和父节点15的左子节点12,它们属于同一层的堂兄弟。根据BST的结构,父节点5 < 父节点15,因此父节点5的后代都小于父节点15的。所以,7 < 15,而12是父节点15的左子节点,因此12 < 15。因此,7 < 15,而12 < 15,但无法直接推断7和12之间的关系。比如,7是否小于12? 由于父节点5的右子节点7必须小于其父节点的父节点10(因为5是10的左子节点,5 < 10,所以5的右子节点7必须满足5 < 7 < 10)。而父节点15的左子节点12必须满足10 < 15,且12 < 15。因此,7 < 10 < 12 < 15。所以,7 < 12。因此,堂兄弟节点7和12的有序,7 < 12。 这表明在BST中,堂兄弟节点可能根据其父节点的位置自然有序,左边的堂兄弟小于右边的堂兄弟。 但需要确认是否所有情况下都成立。比如,是否存在某个BST结构,使得同一层的堂兄弟节点无序? 假设构造一个BST如下: ``` 50 / \ 30 70 / \ / \ 20 40 60 80 / \ / \ 10 25 35 45 ``` 第三层中的堂兄弟节点例如10(父20)、25(父20)、35(父40)、45(父40),他们的父节点20和40都是30的子节点。根据BST的结构,20 < 30 < 40。父节点20的右子节点25必须满足20 < 25 < 30,而父节点40的左子节点35必须满足30 < 35 < 40。因此,25 < 35。同样,父节点20的左子节点10 < 20,父节点40的右子节点45 > 40,所以10 < 45。因此,所有左边的堂兄弟节点都小于右边的堂兄弟节点。 看起来,只要BST的结构正确,同一层的堂兄弟节点会按照父节点的顺序排列,从而堂兄弟节点自然有序。这可能是因为在BST中,父节点的位置决定了其子树的的范围,因此不同父节点堂兄弟节点会根据父节点的位置保持顺序。 总结来说,在二叉搜索树中,堂兄弟节点之间可能存在有序性,即左边的堂兄弟节点小于右边的堂兄弟节点。这是因为它们的父节点在BST中已经按左小右大的顺序排列,而每个父节点的子树也遵循同样的规则,导致他们的后代节点自然保持顺序。但需要进一步验证是否存在例外情况,或者是否所有情况下都成立。 可能的例外情况可能出现在不同层级的结构中,或者父节点虽然在不同子树中但相近。例如,如果父节点A在左子树的右端,父节点B在右子树的左端,他们的子节点是否仍然有序? 例如: ``` 100 / \ 50 150 / \ / \ 30 70 130 170 / \ / \ 20 40 60 80 ``` 这里,父节点70(在左子树的右子)和父节点130(在右子树的左子)的子节点。假设父节点70有一个右子节点85,父节点130有一个左子节点125。根据BST规则,70 < 85 < 100 < 125 < 130 < 150。因此,堂兄弟节点85和125的满足85 < 125。 因此,无论父节点处于左子树的右端还是右子树的左端,他们的子节点依然保持左小右大的顺序。 因此,可以推断在正确的二叉搜索树结构中,同一层的堂兄弟节点是有序的,左边的堂兄弟节点小于右边的堂兄弟节点。这是因为整个BST的结构保证了节点的有序层级排列,堂兄弟节点的父节点位置决定了他们的的相对大小。 不过,需要注意的是,这里的分析假设BST是完全符合定义的,即每个节点都严格满足左子树所有节点小于当前节点,右子树所有节点大于当前节点。如果BST的结构被破坏或者插入顺序导致结构不平衡,可能影响堂兄弟节点的有序性。但在标准的BST中,堂兄弟节点的有序性应成立。</think>在二叉搜索树(BST)中,**堂兄弟节点(同一层但父节点不同的节点)是否有序**取决于BST的结构特性。以下是详细分析: --- ### **1. 基本概念** - **二叉搜索树(BST)**: 每个节点的左子树所有节点均小于该节点,右子树所有节点均大于该节点。中序遍历BST会得到一个有序序列。 - **堂兄弟节点**: 同一层(深度相同)但父节点不同的两个节点。例如,根节点的左子节点的子节点与根节点的右子节点的子节点互为堂兄弟。 --- ### **2. 堂兄弟节点的有序性分析** #### **(1)BST的结构特性** - 父节点的位置决定子树范围: 左子树的所有节点 < 父节点 < 右子树的所有节点。 - 层级传递性: 若父节点A在父节点B的左侧,则A的所有后代 < B的所有后代(即使A和B是兄弟节点)。 #### **(2)堂兄弟节点的有序性** - **左侧堂兄弟 < 右侧堂兄弟**: 由于BST的层级传递性,若堂兄弟节点分属不同父节点(如父节点在左子树,另一父节点在右子树),则左子树父节点的后代一定小于右子树父节点的后代。 **示例**: ``` 10 / \ 5 15 / \ / \ 3 7 12 18 ``` 第三层堂兄弟节点:3的左子节点(如1)与15的左子节点(如12)满足 `1 < 12`。 - **同一父节点子树内的堂兄弟**: 若父节点均为左子树或右子树的兄弟节点,其子节点仍按左小右大排列。 **示例**: ``` 20 / \ 10 30 / \ / \ 5 15 25 35 ``` 第三层堂兄弟节点:5的右子节点(如7)与15的左子节点(如12)满足 `7 < 12`。 --- ### **3. 例外情况** - **BST结构被破坏**: 若插入或删除操作破坏了BST的规则(如左子树存在大于父节点),则堂兄弟节点的有序性可能失效。 - **特殊构造的BST**: 通过刻意构造的BST可能暂时打破有序性,但这种情况不符合BST定义,属于无效结构。 --- ### **4. 结论** 在标准的二叉搜索树中,**堂兄弟节点是有序的**,具体表现为: 1. **左子树父节点的后代 < 右子树父节点的后代**。 2. **同一父节点子树内,左子节点的后代 < 右子节点的后代**。 这种有序性源于BST的层级传递特性,确保了整棵树的全局有序性。但需注意,此结论仅适用于严格符合定义的BST。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值