二叉树part6 | ● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

文章目录

  • 654.最大二叉树
    • 思路
    • 代码
  • 617.合并二叉树
    • 思路
    • 代码
  • 700.二叉搜索树中的搜索
    • 思路
    • 代码
  • 98.验证二叉搜索树
    • 思路
    • 官方题解
    • 代码
    • 困难
  • 今日收获


654.最大二叉树

思路

前序遍历构造二叉树。
找出数组中最大值,然后递归处理左右子数组。
时间复杂度On2
空间复杂度On

代码

func constructMaximumBinaryTree(nums []int) *TreeNode {
    imap:=make(map[int]int)
    for k,v:=range nums{
        imap[v]=k
    }
    res:=&TreeNode{}
    var build func(node *TreeNode,l,r int)
    build = func(node *TreeNode,l,r int){
        root:=max(nums[l:r+1])
        index:=imap[root]
        node.Val=root
        if index>l{
            node.Left=&TreeNode{}
            build(node.Left,l,index-1)
        }
        if index<r{
            node.Right=&TreeNode{}
            build(node.Right,index+1,r)
        }
    }
    build(res,0,len(nums)-1)
    return res
}

func max(s []int)int{
    res:=0
    for i:=0;i<len(s);i++{
        if res<s[i]{
            res=s[i]
        }
    }
    return res
}

617.合并二叉树

思路

递归构建。
目的是合并ab树,每一步递归要做的事当前节点的值为a树和b树相加,左子树为a树左子树和b树左子树递归合并,右子树为a树右子树和b树右子树递归合并。
时间复杂度On
空间复杂度On

代码

func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
    res:=&TreeNode{}
    if root1==nil&&root2==nil{
        return nil
    }
    if root1!=nil&&root2!=nil{
        res.Val=root1.Val+root2.Val
        res.Left=mergeTrees(root1.Left,root2.Left)
        res.Right=mergeTrees(root1.Right,root2.Right)
    }else if root1!=nil{
        res.Val=root1.Val
        res.Left=mergeTrees(root1.Left,nil)
        res.Right=mergeTrees(root1.Right,nil)
    }else if root2!=nil{
        res.Val=root2.Val
        res.Right=mergeTrees(nil,root2.Right)
        res.Left=mergeTrees(nil,root2.Left)
    }
    return res
}

700.二叉搜索树中的搜索

思路

二叉搜索树中序遍历迭代即可
时间复杂度On

代码

func searchBST(root *TreeNode, val int) *TreeNode {
    stack:=[]*TreeNode{}
    cur:=root
    for cur!=nil||len(stack)>0{
        for cur!=nil{
            stack=append(stack,cur)
            cur=cur.Left
        }
        cur=stack[len(stack)-1]
        if cur.Val==val{
            return cur
        }
        stack=stack[:len(stack)-1]
        cur=cur.Right
    }
    return nil
}

98.验证二叉搜索树

思路

递归,每一层递归的目的是判断当前节点的左右子树的所有节点是否都小于或大于当前节点,然后再递归地判断左右子树是否是二叉搜索树。
时间复杂度Onlogn
还可以优化

官方题解

要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
时间复杂度On

代码

func isValidBST(root *TreeNode) bool {
    if root==nil{
        return true
    }
    if root.Left!=nil{
        ml,_:=maxmin(root.Left)
        if ml>=root.Val{
            return false
        }
    }
    if root.Right!=nil{
        _,mr:=maxmin(root.Right)
        if mr<=root.Val{
            return false
        }
    }

    return isValidBST(root.Left)&&isValidBST(root.Right)
}

func maxmin(root *TreeNode) (int,int){
    max,min:=root.Val,root.Val
    if root.Left!=nil{
        maxl,minl:=maxmin(root.Left)
        if max<maxl{
            max=maxl
        }
        if min>minl{
            min=minl
        }
    }
    if root.Right!=nil{
        maxr,minr:=maxmin(root.Right)
        if max<maxr{
            max=maxr
        }
        if min>minr{
            min=minr
        }
    }
    return max,min
}

困难

开始递归的条件和者终止条件要保持一致性,比如默认只有节点不为空才开始递归,那么终止条件就可以不写节点为空。


今日收获

根据数组构建二叉树的统一写法。
res:=&TreeNode{}
res.Val=…
res.Left=递归…
验证二叉搜索树的写法。

你可能感兴趣的:(算法题,数据结构,算法)