leetcode—hot100-树1_林冲风雪山神庙的博客-CSDN博客
100. 相同的树
class Solution(object):
def isSameTree(self, p, q):
"""
:type p: TreeNode
:type q: TreeNode
:rtype: bool
"""
if p is None and q is None:
return True
if p is None and q is not None:
return False
if p is not None and q is None:
return False
if p.val!=q.val:
return False
else:
return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
101. 对称二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
def dfs(left,right):
if not left and not right:
return True
if not left or not right:
return False
if left.val != right.val:
return False
return dfs(left.left,right.right) and dfs(left.right,right.left)
return dfs(root.left,root.right)
226. 翻转二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def invertTree(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
if root is None:
return
self.invertTree(root.left)
self.invertTree(root.right)
left=root.left
right=root.right
root.left=right
root.right=left
return root
6018. 根据描述创建二叉树
看一下lru: lru也是用哈希表来存储,key是节点值,value是节点node
用哈希表记录以node为根节点,对应的节点值。为了找整个树的根用。
for k in node.keys():
if k not in c:
return node[k]
if x == 1:
ns.left = ne
else:
ns.right = ne
会改变原哈希表的值
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def createBinaryTree(self, descriptions: List[List[int]]) -> Optional[TreeNode]:
def f(i):
s, e, x = descriptions[i]
c[e] = c.get(e, 0) + 1
if s not in node:
ns = TreeNode(s)
node[s] = ns
else:
ns = node[s]
if e not in node:
ne = TreeNode(e)
node[e] = ne
else:
ne = node[e]
if x == 1:
ns.left = ne
else:
ns.right = ne
node = {}
c = {}
for i in range(len(descriptions)):
f(i)
for k in node.keys():
if k not in c:
return node[k]
作者:qin-qi-shu-hua-2
链接:https://leetcode-cn.com/problems/create-binary-tree-from-descriptions/solution/python-ha-xi-by-qin-qi-shu-hua-2-b768/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
树的路径问题
分为二叉树和多叉树
求树的直径:
- 二叉树的直径是当前节点的,左子树的最大深度,右边子树的最大深度,+1.在求二叉树的直径时,定义一个全局变量,在递归求树深的时候求出这个全局变量最大值。
- 多叉树的直径
543. 二叉树的直径
class Solution:
def diameterOfBinaryTree(self, root: TreeNode) -> int:
self.ans = 1
def depth(node):
# 访问到空节点了,返回0
if not node:
return 0
# 左儿子为根的子树的深度
L = depth(node.left)
# 右儿子为根的子树的深度
R = depth(node.right)
# 计算d_node即L+R+1 并更新ans
self.ans = max(self.ans, L + R + 1)
# 返回该节点为根的子树的深度
return max(L, R) + 1
depth(root)
return self.ans - 1
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/diameter-of-binary-tree/solution/er-cha-shu-de-zhi-jing-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def diameterOfBinaryTree(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.ans = 0
#肯定有一个公共父节点(不一定是根节点)
def dfs(root):
if root is None:
return 0
left = dfs(root.left)
right = dfs(root.right)
self.ans = max(left+right+1,self.ans)
return max(left,right) + 1
tmp_ans = dfs(root)
return self.ans - 1
104. 二叉树的最大深度
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(root):
if not root:
return 0
left = dfs(root.left)
right = dfs(root.right)
return max(left,right)+1
return dfs(root)
1245. 树的直径(多叉树)
方法1 两次遍历
第一次bfs一定会找到最长路径的一个端点。因为随机取一个点,搜到它的最远点时,一定会经过根节点。可把这条路径分为2段,first ->root ->remote. root->remote的距离一定是最长的。
第二次bfs的时候从remote开始,remote->root->anothor_remote.这样找到的就是整个图的最长路径。
方法2: 记录当前节点的最大路径和次大路径
最大路径 ->当前节点 ->次大路径,构成了一个以当前节点为父节点的最长路径。
class Solution(object):
def treeDiameter(self, edges):
"""
:type edges: List[List[int]]
:rtype: int
"""
self.ans = 0
#先建图
import collections
graph = collections.defaultdict(list)
for i in range(len(edges)):
graph[edges[i][0]].append(edges[i][1])
graph[edges[i][1]].append(edges[i][0])
#难点在于从哪个节点开始遍历.
# 从任意顶点开始遍历,在遍历时记录最大值和次大值。因为图是联通的,所以以任意节点开始。都可以遍历到所有节点
def dfs(root,visited):
neighbors = graph[root]
d1,d2,d = 0,0,0
for neighbor in neighbors:
#防止往回遍历
if neighbor in visited:
continue
visited.add(neighbor)
d = dfs(neighbor,visited)
if d > d1:
d1,d2 = d,d1
elif d > d2:
d2 = d
self.ans = max(self.ans,d1+d2)
return max(d1,d2) + 1
visited = set()
visited.add(0)
ans_tmp = dfs(0,visited)
return self.ans
124 二叉树中的最大路径和
返回当前节点的贡献最大值,当前节点的贡献最大值是 roo.val + max(left,right)
因为题目中要求的是序列,所以要返回的是单边最大贡献,这样子方便去进行递归。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def maxPathSum(self, root):
"""
:type root: TreeNode
:rtype: int
"""
#左边最大值 + 根 + 右边最大值,根,左边最大值 + 根,右边最大值+ 根 的最大值
self.ans = float("-inf")
def dfs(root):
if not root:
return 0
left = dfs(root.left)
right = dfs(root.right)
self.ans = max(self.ans,left + root.val + right,root.val,left+root.val,right+root.val)
# self.ans = max(self.ans,left + root.val + right)
return max(root.val + max(left,right),root.val)
# return max(left + root.val + right,root.val,left+root.val,right+root.val)
ans_tmp = dfs(root)
return self.ans
class Solution {
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxGain(root);
return maxSum;
}
public int maxGain(TreeNode node) {
if (node == null) {
return 0;
}
// 递归计算左右子节点的最大贡献值
// 只有在最大贡献值大于 0 时,才会选取对应子节点
int leftGain = Math.max(maxGain(node.left), 0);
int rightGain = Math.max(maxGain(node.right), 0);
// 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
int priceNewpath = node.val + leftGain + rightGain;
// 更新答案
maxSum = Math.max(maxSum, priceNewpath);
// 返回节点的最大贡献值
return node.val + Math.max(leftGain, rightGain);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/er-cha-shu-zhong-de-zui-da-lu-jing-he-by-leetcode-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
6073. 相邻字符不同的最长路径
有case不通过。在遍历相邻节点的时候,不管是不是相同字符,都要进行遍历,不如后续情况可能会找不到。只有不同字符才更新距离,相同字符就不更新距离
class Solution(object):
def longestPath(self, parent, s):
"""
:type parent: List[int]
:type s: str
:rtype: int
"""
#先建树,然后遍历树,在遍历的过程中记录最长路径和次长路径
#递归函数返回 当前节点,和当前节点的单表最大值
self.ans = 0
import collections
graph = collections.defaultdict(list)
for i in range(len(parent)):
graph[parent[i]].append(i)
print(graph)
def dfs(root,visited):
neighbors = graph[root]
d,d1,d2 = 0,0,0
for neighbor in neighbors:
if s[neighbor] != s[root] and neighbor not in visited:
visited.add(neighbor)
d = dfs(neighbor,visited)
if d > d1 :
d1,d2 = d,d1
elif d > d2 :
d2 = d
self.ans = max(self.ans,d1+d2+1)
return max(d1,d2)+1
visited = set()
visited.add(-1)
tmp_ans = dfs(0,visited)
return self.ans
class Solution(object):
def longestPath(self, parent, s):
"""
:type parent: List[int]
:type s: str
:rtype: int
"""
# 先建树,然后遍历树,在遍历的过程中记录最长路径和次长路径
# 递归函数返回 当前节点,和当前节点的单表最大值
self.ans = 0
import collections
graph = collections.defaultdict(list)
for i in range(len(parent)):
graph[parent[i]].append(i)
def dfs(root, visited):
neighbors = graph[root]
d, d1, d2 = 0, 0, 0
for neighbor in neighbors:
if neighbor not in visited:
visited.add(neighbor)
d = dfs(neighbor, visited)
if s[root] == s[neighbor]:
continue
if d > d1:
d1, d2 = d, d1
elif d > d2:
d2 = d
self.ans = max(self.ans, d1 + d2 + 1)
return max(d1, d2) + 1
visited = set()
visited.add(0)
tmp_ans = dfs(0,visited)
return self.ans
236. 二叉树的最近公共祖先
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
#从底向上。这里的底不一定是到叶子结点,当搜到p或者q结点时就返回
def dfs(root,p,q):
if not root or root == p or root == q:
return root
left = dfs(root.left,p,q)
right = dfs(root.right,p,q)
if left and right:
return root
elif left and not right:
return left
elif right and not left:
return right
return dfs(root,p,q)
979. 在二叉树中分配硬币
class Solution:
def distributeCoins(self, root: TreeNode) -> int:
self.step = 0
def dfs(node):
if not node: return 0
left = dfs(node.left)
right = dfs(node.right)
self.step += abs(left) + abs(right)
return left + right + node.val - 1
dfs(root)
return self.step
作者:chenchuxin
链接:https://leetcode.cn/problems/distribute-coins-in-binary-tree/solution/hou-xu-bian-li-by-chenchuxin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。