代码随想录算法训练营第二十二天| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

 654.最大二叉树

题目链接:654.最大二叉树

文档讲解:代码随想录/最大二叉树

视频讲解:视频讲解-最大二叉树

状态:已完成(1遍)

解题过程 

看到题目的第一想法

 我的思路是每次要在当前数组中取出最大的数字,将其赋值给节点,然后将左侧和右侧的数组部分分给左右子节点,依次递归下去。

手搓代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var constructMaximumBinaryTree = function(nums) {
    const maxNode = function(newNum){
        if(newNum.length == 0)return null;
        let maxNum = -1,index = -1;
        for(let i = 0;i<newNum.length;i++){//找出最大值
            if(newNum[i]>maxNum){
                maxNum = newNum[i];
                index = i;//最大值在数组里的索引
            }
        }
        let nd = new TreeNode(maxNum);//赋予当前节点值
        nd.left = maxNode(newNum.slice(0,index));
        nd.right = maxNode(newNum.slice(index+1));
        return nd;
    }
    return maxNode(nums);
};

运行提交都没有问题,不过用时排在垫底,差点超时。

看完代码随想录之后的想法 

这题用递归法的思路是没有问题的,只是在速度上来说,每次构造新数组比较慢,而每次只传入左右两个坐标节点则会更迅速。

讲解代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var constructMaximumBinaryTree = function(nums) {
    const BuildTree = (arr, left, right) => {
        if (left > right)
            return null;
        let maxValue = -1;
        let maxIndex = -1;
        for (let i = left; i <= right; ++i) {
            if (arr[i] > maxValue) {
                maxValue = arr[i];
                maxIndex = i;
            }
        }
        let root = new TreeNode(maxValue);
        root.left = BuildTree(arr, left, maxIndex - 1);
        root.right = BuildTree(arr, maxIndex + 1, right);
        return root;
    }
    let root = BuildTree(nums, 0, nums.length - 1);
    return root;
};

总结

这题认识到了提高运行速度的一种方法,将构造新数组改为传递左右两端点坐标。


 617.合并二叉树

题目链接:617.合并二叉树

文档讲解:代码随想录/合并二叉树

视频讲解:视频讲解-合并二叉树

状态:已完成(1遍)

解题过程  

看到题目的第一想法

这题我第一想法是当前新节点的值等于两个节点的值相加,如果原节点存在,则加值,反之则加0;递归的时候对传入参数要进行判断,如果node1和node1.left都存在,才传入。

手搓代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {TreeNode}
 */
var mergeTrees = function(root1, root2) {
    const mergeTwo = function(node1,node2){
        if(node1 == null&&node2 == null)return null;
        let newNode = new TreeNode();
        newNode.val = (node1?node1.val:0)+(node2?node2.val:0);//如果存在,则取val;如果不存在,则取0
        newNode.left = mergeTwo(node1 && node1.left, node2 && node2.left);//递归之前先判断,如果node1和node1.left都存在,才传入下一层递归
        newNode.right = mergeTwo(node1 && node1.right, node2 && node2.right);
        return newNode;
    }
    return mergeTwo(root1, root2);
};

提交没有问题。 

 看完代码随想录之后的想法 

开头的处理确实让我没想到,如果其中一个没有,直接输出另一个,就算另一个也没有,那就直接为null,也很省力。比我自己的在后面苦苦判断确实省事多了。

讲解代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {TreeNode}
 */
var mergeTrees = function (root1, root2) {
    const preOrder = (root1, root2) => {
        if (!root1)
            return root2
        if (!root2)
            return root1;
        root1.val += root2.val;
        root1.left = preOrder(root1.left, root2.left);
        root1.right = preOrder(root1.right, root2.right);
        return root1;
    }
    return preOrder(root1, root2);
};

总结

这道题要求同时操作两个二叉树,没接触过但也不复杂,只要每次递归传参的时候传两个就可以。


 

 700.二叉搜索树中的搜索

题目链接:700.二叉搜索树中的搜索

文档讲解:代码随想录/二叉搜索树中的搜索

视频讲解:视频讲解-二叉搜索树中的搜索

状态:已完成(1遍)

解题过程  

看到题目的第一想法

搜索树的规律就是左子结点比父节点小,右子节点比父节点大。所以我直接在单层递归的处理中进行判断,将当前节点值和目标值进行比较,如果当前值更大,就往左子结点递归,反之往右子节点递归。

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} val
 * @return {TreeNode}
 */
var searchBST = function(root, val) {
    const findNode = function(node){
        if(node == null)return null;
        if(node.val == val){
            return node;
        }else if(node.val > val){
            return findNode(node.left);
        }else if(node.val < val){
            return findNode(node.right);
        }
    }
    return findNode(root);
};

这里值得注意的是每层递归都得写return。 

 看完代码随想录之后的想法 

确实第一句有简便写法。而且甚至都不用再写个函数。

讲解代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} val
 * @return {TreeNode}
 */
var searchBST = function(root, val) {
    if (!root || root.val === val) {
        return root;
    }
    if (root.val > val)
        return searchBST(root.left, val);
    if (root.val < val)
        return searchBST(root.right, val);
};

总结

 二叉搜索树是位好二叉树哈哈。 

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


 98.验证二叉搜索树

题目链接:98.验证二叉搜索树

文档讲解:代码随想录/验证二叉搜索树

视频讲解:视频讲解-验证二叉搜索树

状态:已完成(1遍)

解题过程 

看到题目的第一想法

 这道题我的想法是每一层都判断一下是不是搜索二叉树,然后将结果返回给上一级父节点。

手搓代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isValidBST = function(root) {
    const see = function(node){
        if(node == null)return true;//空的返回true
        let leftNode = see(node.left);//左子结点递归
        if(node.left&&node.left.val>=node.val)return false;//如果左子结点存在且值大于父节点值,false
        let rightNode = see(node.right);
        if(node.right&&node.right.val<=node.val)return false;//如果右子结点存在且值小于父节点值,false
        return leftNode && rightNode//如果左右子节点都守规矩,那么返回左右子节点是否是搜索二叉树
    }
    return see(root);
};

运行没有问题,但提交只有77/85。

debug了很久发现问题应该出在,我无法判断子节点里是不是所有值都大于或小于父节点,也就是有可能出现左子结点的右子节点比本节点值还要大。所以我想着将一个当前节点的最大最小值记录下来,与父节点比较。

看完代码随想录之后的想法 

看来我犯的错是经典的错误哈哈。这题借用数组的思路十分巧妙,但是讲解的递归法有点难以理解。

讲解代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var isValidBST = function (root) {
    let arr = [];
    const buildArr = (root) => {
        if (root) {
            buildArr(root.left);
            arr.push(root.val);
            buildArr(root.right);
        }
    }
    buildArr(root);
    for (let i = 1; i < arr.length; ++i) {
        if (arr[i] <= arr[i - 1])
            return false;
    }
    return true;
};

总结

既然搜索二叉树是一个有序二叉树,那么将其转换为数组,再来比较数组是否是一个递增数组就好。

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值