22年41周

目录

1.路径总和

2.从中序与后序遍历序列构造二叉树

3.最大二叉树

4.合并二叉树

5.二叉搜索树中的搜索

6.验证二叉搜索树


1.路径总和

题目地址:路径总和

思路:这道题应该用先序的递归遍历来解决,当遍历到叶子节点就判断,总和是否为targetsum。是的话则返回true,否则false

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func hasPathSum(root *TreeNode, targetSum int) bool {
    if root == nil {
        return false
    }
    
    targetSum -= root.Val // 将targetSum在遍历每层的时候都减去本层节点的值
    if root.Left == nil && root.Right == nil && targetSum == 0 { // 如果剩余的targetSum为0, 则正好就是符合的结果
        return true
    }
    return hasPathSum(root.Left, targetSum) || hasPathSum(root.Right, targetSum) // 否则递归找
}

2.从中序与后序遍历序列构造二叉树

链接地址:从中序与后序遍历序列构造二叉树

思想,构造树的过程也是一个递归的过程,从中序和后序中构造二叉树、中序和先序构造二叉树。这两道题的思想时一致的。先从后序遍历中找到根节点的值,之后在中序遍历中找到根节点的值,中序遍历中根节点的边的值是左子树序列,右边是右子树序列。后序遍历中同样是如此,找到根节点的左右子树序列。之后传入到下一轮的递归中。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func buildTree(inorder []int, postorder []int) *TreeNode {


    if len(postorder) == 0{
        return nil
    }
    rootVal := postorder[len(postorder)-1]
    root := &TreeNode{rootVal,nil,nil}

    inorderIndex := 0

    for k,v := range inorder {
        if v == rootVal {
            inorderIndex = k
            break
        }
    }

    root.Left = buildTree(inorder[:inorderIndex],postorder[:inorderIndex])
    root.Right = buildTree(inorder[inorderIndex+1:],postorder[inorderIndex:len(postorder)-1])

    return root

}

3.最大二叉树

最大二叉树

思路:这道题和2中的思路很像,只不过是改成寻找最大值了

/**
 * 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
    }

    max := nums[0]
    maxIndex := 0

    for k,v := range nums {
        if max < v {
            max = v
            maxIndex = k
        }
    }

    root := &TreeNode{max,nil,nil}
    
    root.Left = constructMaximumBinaryTree(nums[:maxIndex])
    
    //这块不用写if判断是否出界的原因是因为[4:4]也是合法的,但是[5:4]就不合法了
    root.Right = constructMaximumBinaryTree(nums[maxIndex+1:])

    
    return root

}

4.合并二叉树

链接:合并二叉树

思想:先序遍历树,可以创建一个新的节点,也可以在两棵子树中的某一棵树上进行操作。

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

5.二叉搜索树中的搜索

链接:二叉搜索树中的搜索

思想:直接利用递归遍历查找即可,找到就返回。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func searchBST(root *TreeNode, val int) *TreeNode {

    if root.Val == val {
        return root
    }

    if root.Left != nil && root.Val > val{
        return searchBST(root.Left,val)
    }

    if root.Right != nil && root.Val < val{
        return searchBST(root.Right,val)
    }

    return nil
}

6.验证二叉搜索树

验证二叉搜索树

思路:分为两种,一种递归法,一种是迭代法,总体思路都是,BST的中序遍历是有序的。递归法需要在递归过程中记录pre节点来完成比较工作。

//二叉搜索树的中序遍历是个有序序列
func isValidBST(root *TreeNode) bool {

    res := make([]int,0)
    if root == nil {
        return false
    }

    stack := make([]*TreeNode,0)
    cur := root
    //迭代法
    for cur != nil ||  len(stack) > 0 {

        if cur != nil {
            stack = append(stack,cur)
            cur = cur.Left
        }else {
            cur = stack[len(stack) - 1]
            res = append(res,cur.Val)
            stack = stack[:len(stack)-1]
            cur = cur.Right
        }

    } 

    for i:=0;i<len(res)-1;i++ {
        if res[i] >= res[i+1] {
            return false
        }
    }

    return true    
}
//递归方法
func isValidBST(root *TreeNode) bool {
    // 保存上一个指针
    var prev *TreeNode
    var travel func(node *TreeNode) bool
    travel = func(node *TreeNode) bool {
        if node == nil {
            return true
        }
        leftRes := travel(node.Left)
        // 当前值小于等于前一个节点的值,返回false
        if prev != nil && node.Val <= prev.Val {
            return false
        }
        prev = node
        rightRes := travel(node.Right)
        return leftRes && rightRes
    }
    return travel(root)
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值