目录
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)