993. 二叉树的堂兄弟节点

分析:
isCousins(root,x,y)能够判断符合值x、y的两个结点是否是堂兄弟结点,普通二叉树
堂兄弟结点是当且仅当x、y位于同一层并且父节点不同时才是堂兄弟结点
x、y的值不相同
设x对应结点p,y对应节点q

思路1

思路1:找到这两个结点,然后记录这两个结点的层次,并且记录这两个结点的父节点是谁,得到以上信息就能判断了
实现是用的层序遍历

class Solution:
    def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
        que = [root]
        layer_x,layer_y = -1,-1
        prex,prey = None,None
        layer = 0
        while que:
            # print([i.val for i in que])
            # print(layer_x,layer_y)
            size = len(que)
            for i in range(size):
                front = que.pop(0)
                # print(front.val)
                # if front.val == x or front.val == y:
                #     continue
                # print(front.val)
                if front.left:
                    que.append(front.left)
                    if front.left.val == x:
                        prex = front
                        layer_x = layer
                    if front.left.val == y:
                        prey = front
                        layer_y = layer
                if front.right:
                    que.append(front.right)
                    if front.right.val == x:
                        prex = front
                        layer_x = layer
                    if front.right.val == y:
                        prey = front
                        layer_y = layer
            layer += 1

        return layer_x == layer_y and prex != prey

写的略丑陋

思路2

思路2:看到提示里面输入的结点数不多,使用先序遍历找到p和q的路径,比较p和q在路径中的位置,并比较路径p和q的父节点是否相同即可

class Solution:
    def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
        # x,y的值不同
        road_x,road_y = [],[]
        self.findRoad(root,x,[],road_x)
        self.findRoad(root,y,[],road_y)        
        # print(road_x,road_y)
        if len(road_x) != len(road_y):
            return False
        elif road_x[-2] == road_y[-2]:
            return False

        return True

    def findRoad(self,root,v,road,res):
        if not root:
            return
        if root.val == v:
            road.append(root.val)
            res.extend(road.copy())
            return 
        road.append(root.val)
        self.findRoad(root.left,v,road,res);
        self.findRoad(root.right,v,road,res)
        road.pop()

findRoad里面我们要用res来存路径
比思路1更清晰一些
在这里插入图片描述

思路3

官方题解,很巧妙的做法,由于输入结点的值是唯一的,而且范围很小,我们可以标记出每个结点的层次和父亲结点,然后直接判断即可
其实只要知道p、q结点的层次和父亲节点这两个信息就行了,思路1是用层序遍历实现、思路2是用先序遍历保存路径实现,思路3是用DFS标记节点实现

class Solution(object):
    def isCousins(self, root, x, y):
        parent = {}
        depth = {}
        def dfs(node, par = None):
            if node:
                depth[node.val] = 1 + depth[par.val] if par else 0
                parent[node.val] = par
                dfs(node.left, node)
                dfs(node.right, node)

        dfs(root)
        return depth[x] == depth[y] and parent[x] != parent[y]

作者:LeetCode
链接:https://leetcode-cn.com/problems/cousins-in-binary-tree/solution/er-cha-shu-de-tang-xiong-di-jie-dian-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个bfs写得很巧妙,能够标记出树中所有节点的父亲结点

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值