二叉树的一些事情
1.二叉树的特点
左<根<右
2. leetcode235 二叉搜索树的最近公共祖先
2.1 遍历二叉树查找
这个方法没有重复利用平衡二叉树的特点: 左<根<右
- 搜索到对应的p和q 所在位置,并记录先前的父节点
- 找到的最后一个共有的节点,也就是最近公共点
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
stack = [([root],root)]
pre_stack = []
while stack:
p_stack, node = stack.pop(-1)
if node.val == p.val or node.val == q.val:
pre_stack.append(p_stack)
if len(pre_stack) ==2:
break
if node.left:
stack.append((p_stack + [node.left],node.left))
if node.right:
stack.append((p_stack+ [node.right],node.right))
i = 0
while i<min(len(pre_stack[0]), len(pre_stack[1])):
if pre_stack[0][i]!=pre_stack[1][i]:
break
res = pre_stack[0][i]
i+=1
return res
2.2 结合二叉搜索树的特性
左节点<根<右节点
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while (root.val-p.val)*(root.val-q.val)>0:
if p.val< root.val:
root = root.left
else:
root = root.right
return root
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
stack = [root]
while stack:
node = stack.pop(-1)
if (node.val - p.val)*(node.val-q.val)>0:
if p.val < node.val:
stack.append(node.left)
else:
stack.append(node.right)
else:
res = node
break
return res
2.3 递归解法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if (root.val-p.val)*(root.val-q.val)<=0:
return root
if p.val < root.val:
return self.lowestCommonAncestor(root.left, p, q)
else:
return self.lowestCommonAncestor(root.right, p, q)
3. leetcode538 把二叉树转为累加树
按照 右 -->根–>左的顺序遍历二叉树,并且修改节点的value
# 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 convertBST(self, root: TreeNode) -> TreeNode:
if not root:
return root
stack = [(0, root)]
res = 0
while stack:
flag, node = stack.pop(-1)
if flag or (not node.left and not node.right):
node.val += res
res = node.val
continue
if node.left:
stack.append((0,node.left))
stack.append((1,node))
if node.right:
stack.append((0,node.right))
return root
4. leetcode449 序列化和反序列二叉树
解决方法:
- 按层次序列化,遇到空节点时用-1表示
- 根据层次反序列化
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root: TreeNode) -> str:
"""Encodes a tree to a single string.
"""
if not root:
return ""
res = []
stack = [root]
res.append(str(root.val))
while stack:
node = stack.pop(-1)
if node.left:
res.append(str(node.left.val))
stack.append(node.left)
else:
res.append(str(-1))
if node.right:
res.append(str(node.right.val))
stack.append(node.right)
else:
res.append(str(-1))
return ",".join(res)
def deserialize(self, data: str) -> TreeNode:
"""Decodes your encoded data to tree.
"""
if not data:
return []
res = list(map(int, data.split(",")))
root = TreeNode(res[0])
stack = [root]
i=1
while stack and i < len(res):
node = stack.pop(-1)
if res[i] !=-1:
node.left = TreeNode(res[i])
stack.append(node.left)
if res[i+1] != -1:
node.right = TreeNode(res[i+1])
stack.append(node.right)
i+=2
return root
5. leetcode1361 验证二叉树
用并查集的方法:
需注意一边merge,一边判断是否二叉树
- 若在操作前,子节点的父,不是本身,则该节点已是别的节点的子节点,则这不是二叉树;
- 若新的父节点的父和子节点的 父相同,(有环),则不是二叉树;
- 若最终的连通图个数>1 ,则不是二叉树。
class Solution:
def validateBinaryTreeNodes(self, n: int, leftChild: List[int], rightChild: List[int]) -> bool:
isVisit = [0]*n
cnt = n
f = [i for i in range(n)]
def getFather(x):
if f[x] == x:
return x
f[x] = getFather(f[x])
return f[x]
def union(x, y):
nonlocal cnt
if y == -1: # child 为空直接返回true
return True
if f[y] != y: # child 已为别人的子节点,返回false
return False
fx = getFather(x)
fy = getFather(y)
if fx==fy: # 父和子的根节点一样, false
return False
else:
cnt -= 1 # 合并一次,连通图个数减一
f[y] = fx
return True
res = []
childs = []
flag = True
for i in range(n):
if rightChild[i]==leftChild[i] and leftChild[i]!= -1:
return False
if not union(i, leftChild[i]) or not union(i, rightChild[i]):
return False
if cnt == 1:
return True
else:
return False