LeetCode刷题日记之搜索二叉树

89 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情
1.最大二叉树

题目描述

image.png

解题思路

由题意可知,需要找到数组中最大值作为根节点,其中根节点左边的作为左子树,右边的作为右子树,左右子树的处理规则相同,显然可以使用递归来处理该问题。
1.确定递归参数及返回值

var traversal = function(nums,left,right) { //直接在原数组上修改,所以需要传入数组起始和终点位置

...
return root
}

2.确认递归终止条件

if(left>=right) { return null // 左指针大于右指针直接返回null }

3.确认单层处理逻辑

   let maxValueIndex = left;  // 最大值的索引
   for(let i = left + 1;i < right; i++) {
        if(nums[i] > nums[maxValueIndex]) {
            maxValueIndex = i; // 更新最大值索引
        }
    }

    const root = new TreeNode(nums[maxValueIndex]) // 构造根节点

    root.left = traversal(nums,left,maxValueIndex) // 左闭右开
    root.right = traversal(nums,maxValueIndex+1,right)  // 左闭右开

整体代码

var constructMaximumBinaryTree = function(nums) {
    var traversal = function(nums,left,right) { // left right 直接在原数组上修改
        if(left>=right) {
            return null // 左指针大于右指针直接返回null
        }
        let maxValueIndex = left;  // 最大值的索引
        for(let i = left + 1;i < right; i++) {
            if(nums[i] > nums[maxValueIndex]) {
                maxValueIndex = i; // 更新最大值索引
            }
        }

        const root = new TreeNode(nums[maxValueIndex]) // 构造根节点

        root.left = traversal(nums,left,maxValueIndex) // 左闭右开
        root.right = traversal(nums,maxValueIndex+1,right)  // 左闭右开

        return root
     }

     return traversal(nums,0,nums.length)
}

2. 合并二叉树

题目描述

image.png

解题思路

本题只需同时遍历两棵二叉树,当遍历的节点一个为空时返回另一个节点,同时不为空时返回两个节点的和

var mergeTrees = function(root1, root2) {
   if(root1 === null) {
       return root2
   } 
   if(root2 === null) {
       return root1
   }

   root1.val += root2.val
   root1.left = mergeTrees(root1.left,root2.left) // 构建左子树
   root1.right = mergeTrees(root1.right,root2.right) // 构建右子树
   return root1
};

3.二叉搜索树中的搜索

题目描述

image.png

解题思路

本题首先需要明白二叉搜索树的定义,二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

由此,我们可以根据值的大小对二叉树进行剪枝,不必遍历整棵二叉树,本题同样可以使用递归法来解决

var searchBST = function(root, val) {
    if(root == null || root.val == val) { // 递归终止条件
        return root
    }
    if(root.val > val) { // 单层处理逻辑
       return  searchBST(root.left,val)
    } 
    if(root.val < val) {
        return searchBST(root.right,val)
    }
};

同样使用迭代法也可以实现,因为树是有序的,可以不用辅助队列来保存节点,直接抛弃不满足的节点即可

var searchBST = function(root, val) {
   while(root){
       if(root.val == val) {
           return root
       } else if(root.val > val) {
           root = root.left
       } else {
           root = root.right
       }
   }

   return null
};

4.验证二叉搜索树

题目描述

image.png

解题思路

因为二叉搜索树使用中序遍历是一个递增的数组,所以该题可以转化为验证中序遍历结果是否是递增的即可,也可在遍历过程中定义一个pre变量,保存当前节点的前一个节点,递归判断是否是递增的即可。

var isValidBST = function(root) {
   let pre = null
   var traversal = function(node) {
       if(node == null) { // 递归终止
           return true
       }
       let left = traversal(node.left) // 左
       if(pre!=null && pre.val>=node.val) { // 判断是否递增
           return false
       }
       
       pre = node  // 中
      

       let right = traversal(node.right) // 右

       return left && right // 左右都是二叉搜索树 返回值
   }

   return traversal(root)
};