leetcode144-二叉树前序遍历
方法二:辅助栈
# 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 preorderTraversal(self, root: TreeNode) -> List[int]:
#
stack,res = [],[]
stack.append(root)
while stack:
node = stack.pop()
if node:
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res
二叉树中序遍历
方法一:递归
方法二:辅助栈
时间复杂度o(n),空间复杂度o(n)
# 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 inorderTraversal(self, root: TreeNode) -> List[int]:
stack,res = [],[]
while stack or root:
if root:
stack.append(root)
root = root.left
else:# 不断往左走
tmp = stack.pop()# 为空则从stack弹出保存最后一个节点的值
res.append(tmp.val)
root = tmp.right# 然后转向右边再持续整个过程
return res
二叉树后序遍历
方法一:递归*
思路:
通过递归判断所有子树的正确性(后序遍历是否满足二叉搜索树的定义)
递归解析:
终止条件: i>=j,说明此子树节点数量<=1
递推工作:
1. 划分左右子树: 遍历[i,j]区间的元素,寻找第一个大于跟节点的节点,索引记为m。所以左子树区间[i,m-1],右子树区间[m,j],跟索引j
2. 判断是否为二叉搜索树:
返回值:
- p == j 判断此树是否正确
- recur(i,m-1) 判断此树的左子树是否正确
- recur(m,j-1) 判断此树的右子树是否正确
时间复杂度:o(n^2) 每次调用recur(i,j)减去一个跟节点,o(n);最差情况下每轮遍历树所有节点(树退化为链表),o(n)
空间复杂度:o(n) 最差情况下,递归深度为n
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
def recur(i,j):
if i >= j:
return True
p = i
while postorder[p] < postorder[j]:
p += 1
m = p
while postorder[p] > postorder[j]:
p += 1
return p == j and recur(i,m-1) and recur(m,j-1)
return recur(0,len(postorder)-1)
方法二:辅助单调栈
补充知识:单调栈
后序遍历倒序:
设后序遍历倒序列表[rn,rn-1,…,r1],遍历此列表,设索引为i
若为二叉搜索树,则:
节点值ri > ri+1,ri为ri+1的右子节点
节点值ri<ri+1,ri为某节点root的左子节点
当遍历时遇到递减节点ri< ri+1,对于后序遍历中节点ri右边的任意节点rx属于[ri-1,…,r1],rx < root
借助单调栈:
- 单调栈stack存储值递增的节点
- 每当遇到值递减的节点ri,通过出栈跟新节点ri的父节点root
- 每轮判断ri和root的值关系
算法流程: - 初始化:
- 倒序遍历,记每个节点为ri(a. 判断,ri>root,返回false;b. 更新root,c。出栈)
- 遍历完成,返回true
时间复杂度:o(n)
空间复杂度:o(n)
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
stack,root = [],float("+inf")
for i in range(len(postorder)-1,-1,-1):
if postorder[i] > root:return False
while (stack and postorder[i] < stack[-1]):
root = stack.pop()
stack.append(postorder[i])
return True
# 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 postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = [root]
res = []
while stack:
s = stack.pop()
res.append(s.val)
if s.left:
stack.append(s.left)
if s.right:
stack.append(s.right)
return res[::-1]# 在前序遍历中,将Left与right交换,输出反转的树