二叉树算法的关键思路
把题目的要求细化,搞清楚根节点应该做什么,进行前/中/后序遍历。
654.最大二叉树
654.最大二叉树(难度 Medium)
提示:
给定的数组的大小在 [1, 1000] 之间。
class Solution:
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if not nums:
return None
if len(nums)==1:
root = TreeNode(nums[0])
return root
max_i = 0
for i in range(1,len(nums)):
if nums[max_i]<nums[i]:
max_i = i
root = TreeNode(nums[max_i])
root.left = self.constructMaximumBinaryTree(nums[:max_i])
root.right = self.constructMaximumBinaryTree(nums[max_i+1:])
return root
105.从前序与中序遍历序列构造二叉树
105.从前序与中序遍历序列构造二叉树(难度 Medium)
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if not preorder or not inorder:
return None
preL = len(preorder)
inL = len(inorder)
if preL!=inL:
return None
root = self.bulid(preorder,0,preL-1,inorder,0,inL-1)
return root
def bulid(self,preorder,pre_left,pre_right,inorder,in_left,in_right):
if pre_left>pre_right or in_left>in_right:
return None
pivot = preorder[pre_left]
pivot_idx = in_left
while inorder[pivot_idx]!= pivot:
pivot_idx += 1
root = TreeNode(pivot)
root.left = self.bulid(preorder,pre_left+1,pre_left+pivot_idx-in_left,
inorder,in_left,pivot_idx-1)
root.right = self.bulid(preorder,pre_left+pivot_idx-in_left+1,pre_right,
inorder,pivot_idx+1,in_right)
return root
复杂度分析:
时间复杂度:O(N2),N是数组的长度,一共生成N个节点,每个节点构造过程中查询pivot在inorder数组中的位置,复杂度为N有关
空间复杂度:O(1),此处不考虑递归栈的空间
优化:
把inorder数组中的元素实现保存在hashmap里,查询的时间复杂度可以减少到O(1)
106.从中序与后序遍历序列构造二叉树
106.从中序与后序遍历序列构造二叉树(难度 Medium)
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
和105思路一样,考虑上一题提到的优化方法。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if len(inorder)!=len(postorder) or not inorder or not postorder:
return None
inorder_dic = {}
for i,n in enumerate(inorder):
inorder_dic[n] = i
return self.build(inorder_dic,0,len(inorder)-1,postorder,0,len(postorder)-1)
def build(self,inorder_dic,in_left,in_right,postorder,po_left,po_right):
if in_left>in_right or po_left>po_right:
return None
pivot = postorder[po_right]
pivot_idx = inorder_dic[pivot]
root = TreeNode(pivot)
root.left = self.build(inorder_dic,in_left,pivot_idx-1,
postorder,po_left,po_left+pivot_idx-in_left-1)
root.right = self.build(inorder_dic,pivot_idx+1,in_right,
postorder,po_left+pivot_idx-in_left,po_right-1)
return root
优化后
参考资料:
https://mp.weixin.qq.com/s/OlpaDhPDTJlQ5MJ8tsARlA