力扣初级——二叉树,解题合集

1 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

    3

   / \

  9  20

    /  \

   15   7

返回它的最大深度 3 。

  解 

/**
 * 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 maxDepth = function(root) {
     return root==null? 0 : Math.max(maxDepth(root.left), maxDepth(root.right))+1;
};

本题比较简单

2验证完全二叉树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。

节点的右子树只包含 大于 当前节点的数。

所有左子树和右子树自身必须也是二叉搜索树。

也就是说 根节点的val永远大于他左边的,不管到了多少层,隔了多少代

右边同样 永远小于

思路1

本题要注意一点,他说的 “左节点包含的树永远小于root” ,也就是说不管隔了多少代,位于节点左侧的树永远小于根节点的值,基于这一点我们便知道,最左侧的值最小,最右侧的值最大。我们可以将数据收容到同一个数组中,比较数值


/**
 * 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) {
      let res = true
    const arr = []
    const inorder = (root) => {
        if(!root) return
        inorder(root.left)
        arr.push(root.val)
        inorder(root.right)
    }
    inorder(root)
    for(let i = 0; i <arr.length-1; i++) {
        if (arr[i] >= arr[i+1] ) {
             res = false
             break
        }
        
    }
    return res
// 作者:数据结构和算法
// 链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn08xg/?discussion=69ga70
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

效率很低,1是操作数据次数多,2是可以在遍历中执行的比较放在了for循环内。但是这个解法很直观,也有利于数据后续处理,但单纯做题来说不适用

思路2 递归


/**
 * 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}
 */
 let prev = null
var isValidBST = function(root) {
     if (root == null)
        return true;
    //访问左子树
    if (!isValidBST(root.left))
        return false;
    //访问当前节点:如果当前节点小于等于中序遍历的前一个节点直接返回false。
    if (prev != null && prev.val >= root.val)
        
        return false;
    prev = root;
    //访问右子树
    if (!isValidBST(root.right))
        return false;
    return true;

这个办法是用一个指针标记了他的前一个遍历的节点,中序遍历顺序正好对应了本题数值大小排序,所以只要比较前一个节点是否大于当前节点就可以判断它是不是完全二叉树

这个办法在提交的时候 输入[0]时无法正确作答,但是在单一运行测试时又是对的 ,目前比较困惑

思路3


/**
 * 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}
 */
 let prev = null
var isValidBST = function(root) {
     if (root == null)
        return true;
    //访问左子树
    if (!isValidBST(root.left))
        return false;
    //访问当前节点:如果当前节点小于等于中序遍历的前一个节点直接返回false。
    if (prev != null && prev.val >= root.val)
        
        return false;
    prev = root;
    //访问右子树
    if (!isValidBST(root.right))
        return false;
    return true;

这个办法是层序遍历,当本层元素全部合法时返回true,如果有一个不合法,true值返回链就会被打断,输出false

本题的运行效率也比较高

3对称二叉树

本题比较简单,可以使用上层层序遍历的思想


/**
 * 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 isSymmetric = function (root) {
    if (root == null) return true;
    const checkRoot = (right, left) => {
        if (left == null && right == null) return true;
        
        if (left == null || right == null || left.val != right.val) return false
        return checkRoot(right.right, left.left) && checkRoot(right.left, left.right)
    }
    return checkRoot(root.right, root.left)
};

这个递归的时候要注意,放进去的是L.L,R.R && L.R,R.L

4 二叉树层序遍历

分层输出二叉树,每层单独是一个数组

这个题比较简单,递归不递归都可以做,这里提供一个不递归的做法(上面基本都是递归),很多场景我们可以利用while达到递归的效果,前提是递归的线路不会扩展


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

不用递归 while循环完成
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function (root) {
    const res = []
    if (root == null) return []
    const temp = []
    temp.push(root)
    while (temp.length > 0) {
        const layerGroup = []
        const n = temp.length
        for (let i = 0; i < n; i++) {
            const target = temp.shift()
            layerGroup.push(target.val)
            if (target.left != null) {
                temp.push(target.left)
            }
            if (target.right != null) {
                temp.push(target.right)
            }
        }
        res.push(layerGroup)
    }
    return res
};

5.数组转化为高度平衡二叉树

平衡的意思是左侧分支与右侧分支总数量差距小于等于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 sortedArrayToBST = function (nums) {
    if (nums.length == 0) return null
    // const root = new TreeNode()
  
    return splitNums(nums,0,nums.length-1)
};
  function splitNums(num, start, end){
        if (start > end) return null;
        let mid = (start + end) >> 1;
        let root = new TreeNode(num[mid])
        root.left = splitNums(num,start ,mid-1)
        root.right = splitNums(num ,mid+1,end)
        return root
    }

这个解法的重点就是指针,可以看到数组被一直传下去了,由中心指针将数组分为高度平衡的两个数组,所以求中值是必须的,然后将新的开始结尾指针传入下一层

当然说是层序思想,但是分析代码行为我们不难看出这个是先序遍历。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸢_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值