代码随想录day17|654最大二叉树617合并二叉树700二叉搜索树中的搜索98验证二叉搜索树|01笔记

54 阅读2分钟
  • 654最大二叉树

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 遍历数组得到最大值构建当前结点,然后再将数组拆分到子树。利用递归构建二叉树。
  • 解题代码

  • 递归的终止逻辑来自于数组拆分后是否还有元素
  •     func constructMaximumBinaryTree(nums []int) *TreeNode {
            if len(nums) == 0 {
                return nil 
            }
            // 找到最大值
            index := findMax(nums)
            // 构造二叉树
            root := &TreeNode {
                Val: nums[index],
                Left: constructMaximumBinaryTree(nums[:index]),   //左半边
                Right: constructMaximumBinaryTree(nums[index+1:]),//右半边
                }
            return root
        }
        func findMax(nums []int) (index int) {
            for i, v := range nums {
                if nums[index] < v {
                    index = i
                }
            }
            return 
        }
    
  • 要注意左闭右开的逻辑
  • 要注意建立新结点时使用&取址
  • 617合并二叉树

  • 代码随想录 (programmercarl.com)
  • 讲解观后感

  • 同时传入两个树的根节点,前序递归遍历。终止方法是当root1为空时返回root2,当root2为空时返回root1。每次传入两树相同位置的结点。
  • 解题代码

  • 直接使用两树原本的结点进行计算和连接操作。
  •     // 前序遍历
        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
        }
    
  • 迭代
  •     // 迭代版本
        func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
            queue := make([]*TreeNode,0)
            if root1 == nil{
                return root2
            }
            if root2 == nil{
                return root1
            }
            queue = append(queue,root1)
            queue = append(queue,root2)
        
            for size := len(queue); size>0; size=len(queue) {
                node1 := queue[0]
                queue = queue[1:]
                node2 := queue[0]
                queue = queue[1:]
                node1.Val += node2.Val
                // 左子树都不为空
                if node1.Left != nil && node2.Left != nil {
                    queue = append(queue,node1.Left)
                    queue = append(queue,node2.Left)
                }
                // 右子树都不为空
                if node1.Right !=nil && node2.Right !=nil {
                    queue = append(queue, node1.Right)
                    queue = append(queue, node2.Right)
                }
                // 树 1 的左子树为 nil,直接接上树 2 的左子树
                if node1.Left == nil {
                    node1.Left = node2.Left
                }
                // 树 1 的右子树为 nil,直接接上树 2 的右子树
                if node1.Right == nil {
                    node1.Right = node2.Right
                }
            }
            return root1
        }
    
  • 700二叉搜索树中的搜索

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 这题考查对于二叉搜索树特性的理解。使用迭代法每次根据目标值与当前结点的比较关系向下查找即可。
  • 讲解观后感

  • 递归查找也可以,利用前序遍历。
  • 解题代码

  • 迭代法
  •      //迭代法
        func searchBST(root *TreeNode, val int) *TreeNode {
            for root != nil {
                if root.Val > val {
                    root = root.Left
                } else if root.Val < val {
                    root = root.Right
                } else {
                    return root
                }
            }
            return nil
        }
    
  • 递归
  •      //递归法
        func searchBST(root *TreeNode, val int) *TreeNode {
            if root == nil || root.Val == val {
                return root
            }
            if root.Val > val {
                return searchBST(root.Left, val)
            }
            return searchBST(root.Right, val)
        }
    
  • 98验证二叉搜索树

  • 代码随想录 (programmercarl.com)
  • 第一印象

  • 根据由根节点向下查找的路径,每一个结点数值都应有一个数值的范围,由其上限和下限组成。也许可以使用递归保存其上下限依次进行比较。
  • 讲解观后感

  • 在二叉搜索树中序遍历后得到的应该是不重复且有序的。利用这一特性,可以更方便的完成这道题。
  • 解题代码

  • 递归检查
  •     /**
         * Definition for a binary tree node.
         * type TreeNode struct {
         *     Val int
         *     Left *TreeNode
         *     Right *TreeNode
         * }
         */
        func isValidBST(root *TreeNode) bool {
        	// 二叉搜索树也可以是空树
            if root == nil {
                return true
            }
            // 由题目中的数据限制可以得出min和max
            return check(root,int(math.MinInt64),int(math.MaxInt64))//也可以不加int()转化
        }
        
        func check(node *TreeNode,min,max int) bool {
            if node == nil {
                return true
            }
        
            if min >= node.Val || max <= node.Val {
                return false
            }
            // 分别对左子树和右子树递归判断,如果左子树和右子树都符合则返回true
            return check(node.Right,node.Val,max) && check(node.Left,min,node.Val)
        }
        
    
  • 中序递归
  •     // 中序遍历解法
        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)
        }