二叉树part6 | ● 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=递归…
验证二叉搜索树的写法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值