654.最大二叉树
# 递归法
# 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 constructMaximumBinaryTree(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
if not nums:
return None
# 找到最大值,构造根节点
max_val = max(nums)
root = TreeNode(max_val)
# 找到分割点,分割左右子树
max_idx = nums.index(max_val)
left_nums = nums[: max_idx]
right_nums = nums[max_idx+1:]
# 递归构造左右子树
root.left = self.constructMaximumBinaryTree(left_nums)
root.right = self.constructMaximumBinaryTree(right_nums)
return root
617.合并二叉树
题目链接:合并二叉树
解法:
递归法:使用前序遍历,采用新建root节点的方式比较直观。实现起来比较直观,难度不大。
迭代法:新建root发现非常写起来很麻烦,采用把右边的二叉树合并到左边的写法。注意每个子节点都是原地修改了自己的值,最终返回的是root1,而不是当前的子节点node1,这里我写错了,看了半天没发现怎么回事。
边界条件:
时间复杂度:
空间复杂度:
# 递归法
# 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 mergeTrees(self, root1, root2):
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: TreeNode
"""
if not root1 and not root2:
return None
if not root1:
return root2
if not root2:
return root1
root = TreeNode(root1.val + root2.val)
root.left = self.mergeTrees(root1.left, root2.left)
root.right = self.mergeTrees(root1.right, root2.right)
return root
# 迭代法:广度优先遍历
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
import collections
class Solution(object):
def mergeTrees(self, root1, root2):
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: TreeNode
"""
if not root1:
return root2
if not root2:
return root1
queue = collections.deque([(root1, root2)])
while queue:
for _ in range(len(queue)):
node1, node2 = queue.popleft()
node1.val += node2.val
if node1.left and node2.left:
queue.append((node1.left, node2.left))
elif not node1.left:
node1.left = node2.left
if node1.right and node2.right:
queue.append((node1.right, node2.right))
elif not node1.right:
node1.right = node2.right
return root1
700.二叉搜索树中的搜索
题目链接:二叉搜索树
解法:
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树。
递归法:主要是确定单层递归的逻辑。因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。
迭代法:用常规的广度优先遍历可以轻松解决。但由于二叉搜索树的特性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。中间节点如果大于val就向左走,如果小于val就向右走,简单到想哭。
边界条件:
时间复杂度:
空间复杂度:
# 递归法
# 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 searchBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if not root or root.val == val:
return root
if root.val > val:
return self.searchBST(root.left, val)
if root.val < val:
return self.searchBST(root.right, val)
# 迭代法
# 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 searchBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
while root:
if root.val > val:
root = root.left
elif root.val < val:
root = root.right
else:
return root
return None
98.验证二叉搜索树
题目链接:验证二叉搜索树
解法:
二叉搜索树中,左子树的所有节点的值,都必须小于中间节点的值;右子树的所有节点的值,都必须大于中间节点的值。主要是所有节点,而不是左节点和右节点。所以可以用中序遍历得到所有节点的值,这个列表里的值必须是递增的序列。
这个题目的陷阱:不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。比如下面的就不是二叉搜索树,因为右子树的6小于根节点10。
递归:实际就是二叉树的中序遍历,需要单独写个递归函数,独立出来。再判断遍历后的数组是否有序。
迭代法:实际就是用栈来实现二叉树的中序遍历。这个逻辑有点难理解,得时常复习。
边界条件:
时间复杂度:
空间复杂度:
# 递归
# 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 isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
# 中序遍历得到所有节点的值
values = self.traversal(root)
# 判断是否单挑递增
for i in range(1, len(values)):
if values[i] <= values[i-1]:
return False
return True
def traversal(self, root):
if not root:
return []
left = self.traversal(root.left)
right = self.traversal(root.right)
return left + [root.val] + right
# 迭代法
# 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 isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
# 中序遍历得到所有节点的值
values = self.iter(root)
# 判断是否单调递增
for i in range(1, len(values)):
if values[i] <= values[i-1]:
return False
return True
def iter(self, root):
stack = []
cur = root
result = []
while cur or stack:
if cur:
stack.append(cur)
cur = cur.left
else:
cur = stack.pop()
result.append(cur.val)
cur = cur.right
return result