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)

 

 

 

 

 

 

 

 

 

 

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