Leetcode-树(四)

 

目录

563. 二叉树的坡度

993. 二叉树的堂兄弟节点

543. 二叉树的直径

1161. 最大层内元素和


563. 二叉树的坡度

https://leetcode-cn.com/problems/binary-tree-tilt/

给定一个二叉树,计算整个树的坡度。一个树的节点的坡度定义即为,该节点左子树的结点之和和右子树结点之和的差的绝对值。空结点的的坡度是0。整个树的坡度就是其所有节点的坡度之和。

提示:任何子树的结点的和不会超过 32 位整数的范围。坡度的值不会超过 32 位整数的范围。

题解

一:遇到一个节点,用其左子树的和减去右子树的和的绝对值累加。关键是遇到一个节点,如何取到他左右子树的和。这边分两个函数,主函数递归节点,dfs函数用来求以某节点为根的子树的和。

class Solution(object):
    def __init__(self):
        self.res = 0

    def findTilt(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root or (not root.left and not root.right):
            return 0 
        self.res += abs(self.dfs(root.left) - self.dfs(root.right))
        self.findTilt(root.left)
        self.findTilt(root.right)
        return self.res
    
    def dfs(self, root):
        cnt = 0
        if not root:
            return cnt
        cnt += self.dfs(root.left)
        cnt += root.val
        cnt += self.dfs(root.right)
        return cnt

法二:一中会重复计算节点为根的子树的和,这边用一个字典来记录已经算过的以该节点为根的子树的和。

class Solution(object):
    def __init__(self):
        self.res = 0
        self.rec = {}

    def findTilt(self, root):
        if not root or (not root.left and not root.right):
            return 0 
        self.res += abs(self.dfs(root.left) - self.dfs(root.right))
        self.findTilt(root.left)
        self.findTilt(root.right)
        return self.res
    
    def dfs(self, root):
        cnt = 0
        if not root:
            return cnt
        if root in self.rec:
            return self.rec[root]
        cnt += self.dfs(root.left)
        cnt += root.val
        cnt += self.dfs(root.right)
        self.rec[root] = cnt
        return cnt

法三:在求和的过程中计算坡度。getSum函数返回的是以root为根的树的和,左子树的和加右子树的和加当前节点的值,可以看到出现了左子树的和,右子树的和,此时可以顺带求一下坡度。

class Solution(object):
    def __init__(self):
        self.res = 0

    def findTilt(self, root):
        def getSum(root):
            if not root:
                return 0
            left_sum = getSum(root.left)
            right_sum = getSum(root.right)
            self.res += abs(left_sum - right_sum)
            return left_sum + right_sum + root.val

        if not root or (not root.left and not root.right):
            return 0 
        getSum(root)
        return self.res

993. 二叉树的堂兄弟节点

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

在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。如果二叉树的两个节点深度相同,但父节点不同,则它们是一对堂兄弟节点。我们给出了具有唯一值的二叉树的根节点 root,以及树中两个不同节点的值 x 和 y。只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true。否则,返回 false。

提示:二叉树的节点数介于 2 到 100 之间。每个节点的值都是唯一的、范围为 1 到 100 的整数。

题解

一:层序遍历,同一层的必定满足深度相同,只要再满足父节点不同即可。

from collections import deque
class Solution(object):
    def isCousins(self, root, x, y):
        """
        :type root: TreeNode
        :type x: int
        :type y: int
        :rtype: bool
        """
        if not root or x == y:
            return False 
        q, rec = deque(), None
        q.append(root)

        while q:
            n, rec = len(q), None
            for i in range(n):
                node = q.popleft()
                if node.left:
                    q.append(node.left)
                    if node.left.val == x or node.left.val == y:
                        if rec and rec != node:
                            return True
                        rec = node 
                if node.right:
                    q.append(node.right)
                    if node.right.val == x or node.right.val == y:
                        if rec and rec != node:
                            return True
                        rec = node 
        return False

法二:dfs,深度优先搜索标记每一个节点,对于每一个节点 root,它的父亲为 father,深度为 depth,并记录在字典中。

class Solution(object):
    def isCousins(self, root, x, y):
        def dfs(root, parient=None):
            if not root:
                return 
            depth[root.val] = (depth[parient.val] if parient else 0) + 1
            father[root.val] = parient.val if parient else None
            dfs(root.left, root)
            dfs(root.right, root)
        
        depth, father = {}, {}
        dfs(root, None)
        return depth.get(x) == depth.get(y) and father.get(x) != father.get(y)

543. 二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

示例 :给定二叉树

返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

注意:两结点之间的路径长度是以它们之间边的数目表示。

题解

一:一个节点的直径,是该节点的左子树的最大深度加右子树的最大深度。depth返回一个节点的最大深度。

class Solution(object):
    def __init__(self):
        self.res = 0

    def diameterOfBinaryTree(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def depth(root):
            if not root:
                return 0
            left_depth = depth(root.left)
            right_depth = depth(root.right)
            self.res = max(self.res, left_depth + right_depth + 1 - 1)
            return max(left_depth, right_depth) + 1
        
        depth(root)
        return self.res

1161. 最大层内元素和

https://leetcode-cn.com/problems/maximum-level-sum-of-a-binary-tree/

给你一个二叉树的根节点 root。设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推。请你找出层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。

提示:

  1. 树中的节点数介于 1 和 10^4 之间
  2. -10^5 <= node.val <= 10^5

题解

一:自然而然的想到层序遍历,按层求和,找到最大的那一层。

from collections import deque
class Solution(object):
    def maxLevelSum(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        q, res = deque(), [] 
        q.append(root) 

        while q:
            n, level_sum = len(q), 0
            for i in range(n):
                node = q.popleft()
                level_sum += node.val 
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
            res.append(level_sum)

        max_num = max(res)

        for i in range(len(res)):
            if res[i] == max_num:
                return i + 1

二:DFS,递归的时候要加入层信息,并用一个字典来求各层的和。

from collections import defaultdict
class Solution(object):
    def maxLevelSum(self, root):
        def dfs(root, level):
            if not root:
                return 
            level_sum[level] += root.val 
            dfs(root.left, level + 1)
            dfs(root.right, level + 1)

        level_sum = defaultdict(int)
        dfs(root, 1)
        return max(level_sum, key=level_sum.get)

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章