目錄
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
和10^4
之間 -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)