格式:
题号+题名+简单思路+code
二叉树的遍历汇总
递归解法
- 示前序遍历,三种遍历基本类似
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func preorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
assist(root,&ans)
return ans
}
func assist(root *TreeNode,list *[]int) {
if root==nil {
return
}
// 三种遍历更改处
*list=append(*list,root.Val)
assist(root.Left,list)
assist(root.Right,list)
}
栈解法
- 前序遍历(切片实现栈)
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func preorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
tmp:=[]*TreeNode{root}
for len(tmp)>0 {
node:=tmp[len(tmp)-1]
ans=append(ans,node.Val)
tmp=tmp[:len(tmp)-1]
if node.Right!=nil {
tmp=append(tmp,node.Right)
}
if node.Left!=nil {
tmp=append(tmp,node.Left)
}
}
return ans
}
- 前序遍历(双链表实现栈)
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
import "container/list"
func preorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
tmp:=list.New()
tmp.PushBack(root)
for node:=tmp.Back();node!=nil;node=tmp.Back() {
value:=node.Value.(*TreeNode)
ans=append(ans,value.Val)
tmp.Remove(node)
if value.Right!=nil {
tmp.PushBack(value.Right)
}
if value.Left!=nil {
tmp.PushBack(value.Left)
}
}
return ans
}
- 中序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func inorderTraversal(root *TreeNode) []int {
ans:=[]int{}
stack:=[]*TreeNode{}
curr:=root
for len(stack)>0 || curr!=nil {
for curr!=nil {
stack=append(stack,curr)
curr=curr.Left
}
if len(stack)>0 {
node:=stack[len(stack)-1]
stack=stack[:len(stack)-1]
ans=append(ans,node.Val)
curr=node.Right
}
}
return ans
}
- 后序遍历
- 根-右-左的逆序,类似前序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func postorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
tmp:=[]*TreeNode{root}
for len(tmp)>0 {
node:=tmp[len(tmp)-1]
tmp=tmp[:len(tmp)-1]
ans=append([]int{node.Val},ans...)
if node.Left!=nil {
tmp=append(tmp,node.Left)
}
if node.Right!=nil {
tmp=append(tmp,node.Right)
}
}
return ans
}
颜色标记法
- 示前序遍历,三种遍历基本类似
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
type Color int
const (
WHITE Color=0
BLACK Color=1
)
func preorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root == nil {
return ans
}
tmp:=[][2]interface{}{[2]interface{}{root,WHITE}}
for len(tmp)>0 {
node:=tmp[len(tmp)-1]
tmp=tmp[:len(tmp)-1]
t_node:=node[0].(*TreeNode)
if t_node==nil {
continue
}
if node[1].(Color)==WHITE {
// 三种遍历更改处
tmp=append(tmp,[2]interface{}{t_node.Right,WHITE})
tmp=append(tmp,[2]interface{}{t_node.Left,WHITE})
tmp=append(tmp,[2]interface{}{t_node,BLACK})
} else {
ans=append(ans,t_node.Val)
}
}
return ans
}
- 示后序遍历
type Color int
const (
WHITE Color=0
BLACK Color=1
)
func postorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root == nil {
return ans
}
tmp:=[][2]interface{}{[2]interface{}{root,WHITE}}
for len(tmp)>0 {
node:=tmp[len(tmp)-1]
tmp=tmp[:len(tmp)-1]
t_node:=node[0].(*TreeNode)
if t_node==nil {
continue
}
if node[1].(Color)==WHITE {
tmp=append(tmp,[2]interface{}{t_node,BLACK})
tmp=append(tmp,[2]interface{}{t_node.Right,WHITE})
tmp=append(tmp,[2]interface{}{t_node.Left,WHITE})
} else {
ans=append(ans,t_node.Val)
}
}
return ans
}
Morris遍历
- 参考
- 前序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func preorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
curr:=root
for curr!=nil {
if left:=curr.Left;left!=nil {
prev:=findPrev(curr)
if prev.Right==nil {
ans=append(ans,curr.Val)
prev.Right=curr
curr=left
} else {
curr=curr.Right
prev.Right=nil
}
} else {
ans=append(ans,curr.Val)
curr=curr.Right
}
}
return ans
}
func findPrev(curr *TreeNode) *TreeNode {
t_node:=curr.Left
for t_node.Right!=nil && t_node.Right!=curr {
t_node=t_node.Right
}
return t_node
}
- 中序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func inorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
curr:=root
for curr!=nil {
if left:=curr.Left;left!=nil {
prev:=findPrev(curr)
if prev.Right==nil {
prev.Right=curr
curr=left
} else {
ans=append(ans,curr.Val)
curr=curr.Right
prev.Right=nil
}
} else {
ans=append(ans,curr.Val)
curr=curr.Right
}
}
return ans
}
func findPrev(curr *TreeNode) *TreeNode {
t_node:=curr.Left
for t_node.Right!=nil && t_node.Right!=curr {
t_node=t_node.Right
}
return t_node
}
- 后序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func postorderTraversal(root *TreeNode) []int {
ans:=[]int{}
if root==nil {
return ans
}
curr:=root
for curr!=nil {
if right:=curr.Right;right!=nil {
prev:=findPrev(curr)
if prev.Left==nil {
ans=append([]int{curr.Val},ans...)
prev.Left=curr
curr=right
} else {
curr=curr.Left
prev.Left=nil
}
} else {
ans=append([]int{curr.Val},ans...)
curr=curr.Left
}
}
return ans
}
func findPrev(curr *TreeNode) *TreeNode {
t_node:=curr.Right
for t_node.Left!=nil && t_node.Left!=curr {
t_node=t_node.Left
}
return t_node
}
层序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func levelOrder(root *TreeNode) [][]int {
ans:=make([][]int,0)
if root==nil {
return ans
}
arr1:=[]*TreeNode{root}
for len(arr1) > 0 {
tmp:=make([]int,len(arr1))
arr2:=[]*TreeNode{}
for idx,node := range arr1 {
tmp[idx]=node.Val
if node.Left!=nil {
arr2=append(arr2,node.Left)
}
if node.Right!=nil {
arr2=append(arr2,node.Right)
}
}
ans=append(ans,tmp)
arr1=arr2
}
return ans
}
T96: 给出不同的二叉搜索树数目
- 利用了BST的性质;这里为了避免重复计算,只算半边
- 记忆化递归
- Catalan数
var memo map[int]int=map[int]int{0:1,1:1}
func numTrees(n int) int {
if v,ok:=memo[n];ok {
return v
}
v:=0
if n%2==1 {
for i:=0;i<n/2;i++ {
v+=numTrees(i)*numTrees(n-1-i)
}
v*=2
v+=numTrees(n/2)*numTrees(n-1-n/2)
} else {
for i:=0;i<n/2;i++ {
v+=numTrees(i)*numTrees(n-1-i)
}
v*=2
}
memo[n]=v
return v
}
T95: 给出不同的二叉搜索树
- 与T96类似
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func generateTrees(n int) []*TreeNode {
if n==0 {
return nil
}
data:=make([]int,n)
for i:=1;i<=n;i++ {
data[i-1]=i
}
return generateTreesAssist(data)
}
func generateTreesAssist(data []int) []*TreeNode {
if len(data)==0 {
return []*TreeNode{nil}
}
ans:=[]*TreeNode{}
for i:=0;i<len(data);i++ {
list1:=generateTreesAssist(data[:i])
list2:=generateTreesAssist(data[i+1:])
for ix1:=range list1 {
for ix2:=range list2 {
tmp:=&TreeNode{data[i],nil,nil}
tmp.Left=list1[ix1]
tmp.Right=list2[ix2]
ans=append(ans,tmp)
}
}
}
return ans
}
※T98: 验证二叉搜索树
- 给定范围,要求每个节点的值处于该范围内
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
return assist(root, nil, nil)
}
func assist(root *TreeNode, minValue *TreeNode, maxValue *TreeNode) bool {
if root==nil {
return true
}
if minValue!=nil && root.Val<=minValue.Val {
return false
}
if maxValue!=nil && root.Val>=maxValue.Val {
return false
}
return assist(root.Left, minValue, root) && assist(root.Right, root, maxValue)
}
- 利用中序遍历有序
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isValidBST(root *TreeNode) bool {
tmp:=[]*TreeNode{}
m:=0
flag:=false
for len(tmp)>0 || root!=nil {
for root!=nil {
tmp=append(tmp,root)
root=root.Left
}
if len(tmp)>0 {
node:=tmp[len(tmp)-1]
if flag==false {
m=node.Val
flag=true
} else {
if node.Val<=m {
return false
}
m=node.Val
}
tmp=tmp[:len(tmp)-1]
root=node.Right
}
}
return true
}
T226: 翻转二叉树
- 递归
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func invertTree(root *TreeNode) *TreeNode {
if root==nil {
return nil
}
node1:=invertTree(root.Left)
node2:=invertTree(root.Right)
root.Left=node2
root.Right=node1
return root
}
- 迭代;以前序遍历为基础
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func invertTree(root *TreeNode) *TreeNode {
if root==nil {
return nil
}
stack:=[]*TreeNode{root}
for len(stack)>0 {
node:=stack[len(stack)-1]
stack=stack[:len(stack)-1]
if node.Left!=nil {
stack=append(stack, node.Left)
}
if node.Right!=nil {
stack=append(stack, node.Right)
}
node.Left, node.Right=node.Right, node.Left
}
return root
}
T617: 合并二叉树
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func mergeTrees(t1 *TreeNode, t2 *TreeNode) *TreeNode {
if t1==nil {
return t2
}
if t2==nil {
return t1
}
node1:=mergeTrees(t1.Left,t2.Left)
node2:=mergeTrees(t1.Right,t2.Right)
tmp:=&TreeNode{t1.Val+t2.Val,node1,node2}
return tmp
}
T107: 二叉树的层次遍历Ⅱ
func levelOrderBottom(root *TreeNode) [][]int {
if root==nil {
return nil
}
ans:=[][]int{}
list:=[]*TreeNode{root}
for len(list)>0 {
tmp:=[]*TreeNode{}
t_ans:=[]int{}
for _,node:=range list {
t_ans=append(t_ans,node.Val)
if node.Left!=nil {
tmp=append(tmp,node.Left)
}
if node.Right!=nil {
tmp=append(tmp,node.Right)
}
}
list=tmp
ans=append(ans, t_ans)
}
// 翻转
for start, end:=0, len(ans)-1;start<end;start, end=start+1, end-1 {
ans[start], ans[end]=ans[end], ans[start]
}
return ans
}
T199: 二叉树的右视图
- 每层最右节点
# 更新每个depth下的节点,最后一个即最右
class Solution:
def rightSideView(self, root):
rightmost_value_at_depth = dict() # 深度为索引,存放节点的值
max_depth = -1
queue = deque([(root, 0)])
while queue:
node, depth = queue.popleft()
if node is not None:
# 维护二叉树的最大深度
max_depth = max(max_depth, depth)
# 由于每一层最后一个访问到的节点才是我们要的答案,因此不断更新对应深度的信息即可
rightmost_value_at_depth[depth] = node.val
queue.append((node.left, depth+1))
queue.append((node.right, depth+1))
return [rightmost_value_at_depth[depth] for depth in range(max_depth+1)]
# 以每层为单位遍历
class Solution:
def rightSideView(self, root: TreeNode) -> List[int]:
if root==None:
return []
queue=[root]
ans=[]
while len(queue)>0:
tmp=[]
ans.append(queue[-1].val)
for node in queue:
if node.left!=None:
tmp.append(node.left)
if node.right!=None:
tmp.append(node.right)
queue=tmp
return ans
T108: 将有序数组转换为平衡二叉搜索树
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func sortedArrayToBST(nums []int) *TreeNode {
if len(nums)==0 {
return nil
}
if len(nums)==1 {
return &TreeNode{nums[0],nil,nil}
}
mid:=len(nums)/2
node:=&TreeNode{nums[mid],sortedArrayToBST(nums[:mid]),sortedArrayToBST(nums[mid+1:])}
return node
}
T114: 二叉树展开为链表
- 基于前序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func flatten(root *TreeNode) {
if root==nil {
return
}
stack:=[]*TreeNode{root}
ans:=new(TreeNode)
curr:=ans
for len(stack)>0 {
node:=stack[len(stack)-1]
stack=stack[:len(stack)-1]
if node.Right!=nil {
stack=append(stack,node.Right)
}
if node.Left!=nil {
stack=append(stack,node.Left)
}
node.Left=nil
curr.Right=node
curr=curr.Right
}
}
T101: 对称二叉树
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSymmetric(root *TreeNode) bool {
return assist(root,root)
}
func assist(root1 *TreeNode,root2 *TreeNode) bool {
if root1==nil && root2==nil {
return true
}
if root1==nil || root2==nil {
return false
}
if root1.Val != root2.Val {
return false
}
return assist(root1.Left,root2.Right) && assist(root1.Right,root2.Left)
}
T654: 最大二叉树
- 类似T108
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func constructMaximumBinaryTree(nums []int) *TreeNode {
if len(nums)==0 {
return nil
}
idx:=0
for i:=1;i<len(nums);i++ {
if nums[i]>nums[idx] {
idx=i
}
}
node:=&TreeNode{nums[idx],constructMaximumBinaryTree(nums[:idx]),constructMaximumBinaryTree(nums[idx+1:])}
return node
}
T110: 平衡二叉树
- 注意避免重复计算的写法
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
if self.assist(root)==-1:
return False
return True
def assist(self, root):
if root==None:
return 0
n1=self.assist(root.left)
if n1==-1:
return -1
n2=self.assist(root.right)
if n2==-1:
return -1
if abs(n1-n2)>1:
return -1
return max(n1,n2)+1
※T655: 输出二叉树
- 先预分配好数组,再以中点形式填充
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
import "strconv"
func printTree(root *TreeNode) [][]string {
height:=getHeight(root)
length:=(1<<height)-1
ans:=make([][]string,height)
for i:=0;i<height;i++ {
ans[i]=make([]string,length)
}
assign(ans,0,0,length-1,root)
return ans
}
func assign(list [][]string,index int,lo int,hi int,node *TreeNode) {
if node==nil {
return
}
mid:=(hi-lo)/2+lo
word:=strconv.Itoa(node.Val)
list[index][mid]=word
assign(list,index+1,lo,mid-1,node.Left)
assign(list,index+1,mid+1,hi,node.Right)
}
func getHeight(node *TreeNode) int {
if node==nil {
return 0
}
h1:=getHeight(node.Left)
h2:=getHeight(node.Right)
if h1>=h2 {
return h1+1
} else {
return h2+1
}
}
※T105: 从前序与中序遍历构造二叉树
- 前序遍历提供root节点;中序遍历提供左右子树的范围
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(preorder []int, inorder []int) *TreeNode {
return assist(preorder,inorder,0)
}
func assist(preorder []int, inorder []int, root int) *TreeNode {
if len(inorder)==0 {
return nil
}
value:=preorder[root]
node:=&TreeNode{value,nil,nil}
index:=0
for ;index<len(inorder);index++ {
if inorder[index]==value {
break
}
}
node.Left=assist(preorder,inorder[:index],root+1)
node.Right=assist(preorder,inorder[index+1:],root+index+1)
return node
}
- 另一种写法
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(preorder []int, inorder []int) *TreeNode {
if len(preorder)==0 {
return nil
}
return buildTreeAssist(preorder, inorder, 0, 0, len(inorder)-1)
}
func buildTreeAssist(preorder []int, inorder []int, index int, lo int, hi int) *TreeNode {
if lo>hi {
return nil
}
value:=preorder[index]
loc:=0
for i:=lo;i<=hi;i++ {
if inorder[i]==value {
loc=i
break
}
}
return &TreeNode{value, buildTreeAssist(preorder, inorder, index+1, lo, loc-1), buildTreeAssist(preorder, inorder, index+loc-lo+1, loc+1, hi)}
}
T112: 路径总和
- 递归解法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if root==None:
return False
return self.assist(root, 0, sum)
def assist(self, root: TreeNode, currSum: int, sum: int) -> bool:
if root.left==None and root.right==None:
if currSum+root.val==sum:
return True
return False
if root.left!=None and self.assist(root.left, currSum+root.val, sum):
return True
if root.right!=None and self.assist(root.right, currSum+root.val, sum):
return True
return False
- 迭代解法
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
type MyTreeNode struct {
currSum int
node *TreeNode
}
func hasPathSum(root *TreeNode, sum int) bool {
if root==nil {
return false
}
point:=MyTreeNode{0,root}
stack:=[]MyTreeNode{point}
for len(stack)>0 {
x:=stack[len(stack)-1]
v:=x.currSum
if x.node.Left==nil && x.node.Right==nil && v+x.node.Val==sum {
return true
}
stack=stack[:len(stack)-1]
if x.node.Right!=nil {
stack=append(stack,MyTreeNode{v+x.node.Val,x.node.Right})
}
if x.node.Left!=nil {
stack=append(stack,MyTreeNode{v+x.node.Val,x.node.Left})
}
}
return false
}
※T113: 路径总和II
- 回溯法
- 深拷贝
copy(tmp_ans,*tmp)
- 伪深拷贝
*tmp=(*tmp)[:len(*tmp)-1:len(*tmp)-1]
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func pathSum(root *TreeNode, sum int) [][]int {
if root==nil {
return nil
}
tmp:=[]int{}
ans:=[][]int{}
pathSumAssist(root, sum, 0, &ans, &tmp)
return ans
}
func pathSumAssist(root *TreeNode, sum int, currSum int, ans *[][]int, tmp *[]int) {
*tmp=append(*tmp, root.Val)
if root.Left==nil && root.Right==nil {
if currSum+root.Val==sum {
res:=make([]int, len(*tmp))
copy(res, *tmp)
*ans=append(*ans, res)
}
*tmp=(*tmp)[:len(*tmp)-1]
return
}
if root.Left!=nil {
pathSumAssist(root.Left, sum, currSum+root.Val, ans, tmp)
}
if root.Right!=nil {
pathSumAssist(root.Right, sum, currSum+root.Val, ans, tmp)
}
*tmp=(*tmp)[:len(*tmp)-1]
}
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
ans=[]
self.pathSumAssist(root, 0, [], sum, ans)
return ans
def pathSumAssist(self, root, currSum, path, sum, ans):
if root==None:
return
path.append(root.val)
if root.left==None and root.right==None:
if currSum+root.val==sum:
ans.append(path[:])
path.pop()
return
self.pathSumAssist(root.left, currSum+root.val, path, sum, ans)
self.pathSumAssist(root.right, currSum+root.val, path, sum, ans)
path.pop()
※T437: 路径总和Ⅲ
count
求出以该节点为顶点的符合要求的路径数pathSum
求出以该节点为root的符合要求的路径数- 不具有重叠子问题性质
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func pathSum(root *TreeNode, sum int) int {
if root==nil {
return 0
}
return pathSum(root.Left, sum)+pathSum(root.Right, sum)+count(root, 0, sum)
}
func count(root *TreeNode, currSum int, sum int) int {
if root==nil {
return 0
}
tmp:=0
if currSum+root.Val==sum {
tmp=1
}
i1:=count(root.Left, currSum+root.Val, sum)
i2:=count(root.Right, currSum+root.Val, sum)
return i1+i2+tmp
}
T124: 二叉树中的最大路径
- 计算每个节点的最大单边路径
- 穷举每个节点的双边路径,取最值
- O(N)
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
import "math"
func maxPathSum(root *TreeNode) int {
result:=math.Inf(-1)
assist(root,&result)
return int(result)
}
func assist(node *TreeNode, result *float64) float64 {
if node==nil {
return 0.0
}
left:=math.Max(assist(node.Left,result),0.0)
right:=math.Max(assist(node.Right,result),0.0)
*result=math.Max(left+right+float64(node.Val),*result)
return math.Max(left,right)+float64(node.Val)
}
T99: 恢复二叉树
- 中序遍历:得到部分有序列表(O(N))
- 再次遍历找到两个需要交换的坐标(第一个出现和最后一个出现)(O(N))
- 再次遍历(利用指针代替全局变量)(O(N))
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func recoverTree(root *TreeNode) {
ans:=[]int{}
inorderTranversal(root,&ans)
loc:=findLocation(ans)
currIndex:=0
inorderTranversalFix(root,loc[0],loc[1],ans,&currIndex)
}
func inorderTranversalFix(root *TreeNode, index1 int, index2 int, ans []int, currIndex *int) {
if root==nil {
return
}
inorderTranversalFix(root.Left,index1,index2,ans,currIndex)
if *currIndex==index1 {
root.Val=ans[index2]
} else if *currIndex==index2 {
root.Val=ans[index1]
}
(*currIndex)++
inorderTranversalFix(root.Right,index1,index2,ans,currIndex)
}
func inorderTranversal(root *TreeNode, ans *[]int) {
if root==nil {
return
}
inorderTranversal(root.Left, ans)
*ans=append(*ans,root.Val)
inorderTranversal(root.Right, ans)
}
func findLocation(list []int) [2]int {
ans:=[2]int{-1,-1}
for i:=0;i<len(list);i++ {
if i==0 {
if list[1]<list[0] {
ans[0]=i
}
} else if i==len(list)-1 {
if list[i-1]>list[i] {
ans[1]=i
}
} else {
if list[i-1]<=list[i] && list[i+1]<=list[i] && ans[0]==-1 {
fmt.Println(i)
ans[0]=i
} else if list[i-1]>=list[i] && list[i+1]>=list[i] {
ans[1]=i
}
}
}
return ans
}
T116: 填充满二叉树中每个节点的下一个右侧指针
- 如何使用给定的next指针来替代O(N)空间复杂度的层序遍历
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if (root==null) {
return root;
}
Node node = root;
while (node.left != null) {
Node tmp = node;
while (tmp!=null) {
tmp.left.next=tmp.right;
if (tmp.next!=null) {
tmp.right.next=tmp.next.left;
}
tmp=tmp.next;
}
node=node.left;
}
return root;
}
}
T236: 二叉树的最近公共祖先
- 递归法逻辑复杂;O(N)时间复杂度
- f ( x ) f(x) f(x)为该节点以及子节点中是否包含 p 或 q p或q p或q
- ( f ( l e f t ) ∧ f ( r i g h t ) ) ∨ ( ( x = p ∨ x = q ) ∧ ( f ( l e f t ) ∨ f ( r i g h t ) ) ) (f(left) \land f(right)) \lor ((x=p \lor x=q) \land (f(left) \lor f(right))) (f(left)∧f(right))∨((x=p∨x=q)∧(f(left)∨f(right)))
/**
* Definition for TreeNode.
* type TreeNode struct {
* Val int
* Left *ListNode
* Right *ListNode
* }
*/
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root==nil {
return nil
}
if root==p || root==q {
return root
}
left:=lowestCommonAncestor(root.Left, p, q)
right:=lowestCommonAncestor(root.Right, p, q)
if left!=nil && right!=nil { // 相当于同时包括了逻辑式的两种情形
return root
}
if left!=nil {
return left
}
return right
}
- 存储父节点;思路简单,O(N+2logN)时间复杂度
/**
* Definition for TreeNode.
* type TreeNode struct {
* Val int
* Left *ListNode
* Right *ListNode
* }
*/
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root==nil {
return nil
}
father_map:=map[*TreeNode]*TreeNode{root:root}
preOrderT(root, father_map)
memo_p:=map[*TreeNode]struct{}{}
tmp:=p
for father_map[tmp]!=tmp {
memo_p[tmp]=struct{}{}
tmp=father_map[tmp]
}
tmp=q
for father_map[tmp]!=tmp {
if _,ok:=memo_p[tmp];ok {
return tmp
}
tmp=father_map[tmp]
}
return root
}
func preOrderT(root *TreeNode, father_map map[*TreeNode]*TreeNode) {
if root==nil {
return
}
if root.Left!=nil {
father_map[root.Left]=root
}
if root.Right!=nil {
father_map[root.Right]=root
}
preOrderT(root.Left, father_map)
preOrderT(root.Right, father_map)
}
T222: 完全二叉树的节点个数
- 注意需要通过深度利用完全二叉树的性质
public class T222 {
public int countNodes(TreeNode root) {
if (root==null) {
return 0;
}
int l1 = getDepth(root.left);
int l2 = getDepth(root.right);
if (l1==l2) {
return (1<<l1)+countNodes(root.right);
} else {
return (1<<l2)+countNodes(root.left);
}
}
public int getDepth(TreeNode node) {
if (node==null) {
return 0;
}
return getDepth(node.left)+1;
}
}
剑指68: 二叉搜索树的最近公共祖先
- BST的性质;可根据节点大小判断p/q位于当前节点的左/右子树
- LCS;要么p和q一个小于当前节点一个大于当前节点,要么p和q有一个为当前节点
- 否则根据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':
if root==None:
return None
if p.val==root.val:
return p
if q.val==root.val:
return q
tmp=(p.val-root.val)*(q.val-root.val)
if tmp<0:
return root
else:
if p.val>root.val:
return self.lowestCommonAncestor(root.right, p, q)
else:
return self.lowestCommonAncestor(root.left, p, q)
剑指26: 树的子结构
- 要么以该节点为root的树A能包含树B;要么以该节点左右子节点为root的树A能包含B
- 包含的写法与相等的区分
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func isSubStructure(A *TreeNode, B *TreeNode) bool {
if B==nil {
return false
}
if A==nil {
return false
}
if isContain(A, B) {
return true
}
return isSubStructure(A.Left, B) || isSubStructure(A.Right, B)
}
func isContain(A *TreeNode, B *TreeNode) bool {
if B==nil {
return true
}
if A==nil {
return false
}
if A.Val!=B.Val {
return false
}
return isContain(A.Left, B.Left) && isContain(A.Right, B.Right)
}
剑指36: 二叉搜索树与双向链表
- 中序遍历保存节点指针,再更改节点关系
"""
# Definition for a Node.
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
"""
class Solution:
def treeToDoublyList(self, root: 'Node') -> 'Node':
if root==None:
return None
tmp=[]
self.assist(root,tmp)
for i in range(len(tmp)-1):
tmp[i].right=tmp[i+1]
tmp[len(tmp)-1-i].left=tmp[len(tmp)-1-i-1]
tmp[0].left=tmp[-1]
tmp[-1].right=tmp[0]
return tmp[0]
def assist(self, root, tmp):
if root==None:
return
self.assist(root.left, tmp)
tmp.append(root)
self.assist(root.right, tmp)
※剑指37: 序列化二叉树
- 基本思路:层序遍历输出字符串,再使用完全二叉树的索引递归建立二叉树
- 为了减少null,左子节点索引为2*(index-zero)+1
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
queue=[root]
ans=[]
while len(queue)>0:
tmp=[]
flag=False
for node in queue:
if node==None:
ans.append("null")
else:
ans.append(str(node.val))
if node.left!=None or node.right!=None:
flag=True
tmp.append(node.left)
tmp.append(node.right)
if flag==False:
break
queue=tmp
return "["+",".join(ans)+"]"
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
ans=data[1:-1].split(",")
zero=[]
count=0
for i in range(len(ans)):
if ans[i]=="null":
count+=1
zero.append(count)
return self.assist(ans, 0, zero)
def assist(self, ans, index, zero):
if index>=len(ans) or ans[index]=="null":
return None
node=TreeNode(int(ans[index]))
node.left=self.assist(ans, 2*(index-zero[index])+1, zero)
node.right=self.assist(ans, 2*(index-zero[index])+2, zero)
return node
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
※剑指54: 二叉搜索树的第k大节点
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
node=root
stack=[]
index=0
while len(stack)>0 or node!=None:
while node!=None:
stack.append(node)
node=node.right
if len(stack)>0:
item=stack.pop()
index+=1
if index==k:
return item.val
node=item.left
return -1
※剑指33: 二叉搜索树的后序遍历序列
- 对给定的后序遍历序列,根节点一定是最后一个
- 由BST性质,假设第一个比根节点大的坐标为i,则可以将该序列分为 [ : i ] [:i] [:i]和 [ i : − 1 ] [i:-1] [i:−1],分别表示左右子树序列,在这里左子树的所有节点一定小于根节点;还需要确定右子树的所有节点均大于根节点
- 递归判断左右子树均为true即可;终止条件为序列长度小于等于1
func verifyPostorder(postorder []int) bool {
if len(postorder)<=1 {
return true
}
val:=postorder[len(postorder)-1]
idx:=len(postorder)-1
for i:=0;i<len(postorder);i++ {
if postorder[i]>val {
idx=i
break
}
}
if !verifyPostorder(postorder[:idx]) {
return false
}
for i:=idx;i<len(postorder)-1;i++ {
if postorder[i]<val {
return false
}
}
if !verifyPostorder(postorder[idx:len(postorder)-1]) {
return false
}
return true
}