题目一描述(重建二叉树)
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题目分析
先序遍历特点:第一个值是根节点(中左右)
中序遍历特点:根节点左边都是左子树,右边都是右子树(左中右)
思路:
首先根据根节点a将中序遍历划分为两部分,左边为左子树,右边为右子树
在左子树中根据第一条规则递归,得出左子树
在右子树中根据第一条规则递归,得出右子树
最后合成一棵树(转自牛客评论)
代码
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# pre具有列表性质
# write code here
if not pre or not tin :
return None
res = TreeNode(pre.pop(0))
index = tin.index(res.val)
res.left = self.reConstructBinaryTree(pre, tin[:index])
# 这里是一个妙处,因为之前是pop函数,pre经过左子树的函数过后,仅仅只剩右子树函数
res.right = self.reConstructBinaryTree(pre, tin[index+1:])
return res
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# write code here
if not pre or not tin:
return None
else:
ans = TreeNode(pre[0])
ans.left = self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1], tin[:tin.index(pre[0])])
ans.right = self.reConstructBinaryTree(pre[tin.index(pre[0])+1:], tin[tin.index(pre[0])+1:])
return ans
题目二描述(第k小元素)
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 1
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 3
题目分析
给的二叉树是按照中序顺序进行的,即将二叉树进行中序遍历,然后选取第k个值即可
中序遍历代码
# 递归版本
class Solution(object):
def inorderTraversal(self, root):
def core(root,res):
if root:
core(root.left,res)
res.append(root.val)
core(root.right,res)
res=[]
core(root,res)
return res
### 循环写法
class Solution(object):
def inorderTraversal(self, root):
stack=[]
res=[]
node=root
while node or len(stack)>0:
if node:
stack.append(node)
node=node.left
else:
node=stack.pop()
res.append(node.val)
node=node.right
return res
题目代码
递归版本
### 中序递归版
class Solution(object):
def kthSmallest(self, root, k):
self.count=k
self.res=0
def core(root):
if root :
core(root.left)
self.count=self.count-1
if self.count==0:
self.res=root.val
core(root.right)
core(root)
return self.res
循环版本
#### 中序循环版本
class Solution(object):
def inorderTraversal(self, root):
stack=[]
res=[]
node=root
while node or len(stack)>0:
if node:
stack.append(node)
node=node.left
else:
node=stack.pop()
res.append(node.val)
node=node.right
return res
题目三–公共祖先
题目描述
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
题目分析
根据BST(二叉搜索树)的特点,节点共三种情况:
p,q都在左子树(二者的值都小于根的值)
p,q都在右子树 (二者的值都大于根的值)
p,q分别在左右子树(此时最近公共祖先为root
代码
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if max(p.val,q.val) < root.val:
return self.lowestCommonAncestor(root.left,p,q)
if min(p.val,q.val) > root.val:
return self.lowestCommonAncestor(root.right,p,q)
return root
当二叉树不是搜索二叉树时:
题目分析
后序遍历(自底向上)。一旦遇到p、q、满足条件的节点,就向上传递,最后传递到顶端的就是满足条件的节点
# 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
"""
if root == None or root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
## 由下而上考虑 如果符合条件就把符合条件的节点向上传递
if left and right:
return root
## 由下而上考虑 如果满足左右两边都有p,q
return left if left else right