Leetcode(3)——二叉树

格式:

题号+题名+简单思路+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 pq
  • ( 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=px=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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值