二叉树(力扣hot)

45 阅读5分钟

力扣对应的二叉树题有15道

94. 二叉树的中序遍历

解题思路:中序遍历,使用递归,注意node.val的存储时机

/**
 * 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 inorderTraversal=(root)=>{ 
    let res = [];
    const dfs = (root)=>{
        if(root == null) return;
        dfs(root.left)
        res.push(root.val)
        dfs(root.right)
    }
    dfs(root)
    return res
}
 // 迭代法
var inorderTraversal=(root)=>{ 
    let res = [];
    let stock = [];
    let curr = root;
    while(stock.length || curr){
        if(curr){
            stock.push(curr);
            curr = curr.left
        }else{
            curr = stock.pop();
            res.push(curr.val);
            curr = curr.right
        }
    }
    return res
}

力扣104. 二叉树的最大深度

解题思路:两个思路,1.层序遍历,遍历有多少层 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 {number}
 */
var maxDepth=(root)=>{
    let res = [];
    let quene = [root];
    while(quene.length !== 0){
        let len = quene.length;
        let arr = [];
        for(let i=0;i<len;i++){
            let node = quene.shift();
            arr.push(node.val);
            node.left && quene.push(node.left);
            node.right && quenen.push(node.right)
        }
        res.push(arr)
    }
    return res.length

}
var maxDepth=(root)=>{
    const dfs = (node)=>{
        if(node == null) return 0
        return 1 + Math.max(dfs(node.left),dfs(node.right))
    }
   
    return dfs(root)

}

力扣226.翻转二叉树

解题思路:层序遍历,对每个节点交换左右子节点

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

const invertTree=(root)=>{
    if(root == null) return root;
    let quene = [root];
    while(quene.length !== 0){
         let len = quene.length;
         for(let i=0;i<len;i++){
             let node = quene.shift();
             const template = node.left;
             node.left = node.right;
             node.right = template;
             node.left && quene.push(node.left);
             node.right && quene.push(node.right)
         }
    }
    return root
}

力扣101.对称二叉树

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

力扣543.二叉树的直径


/**
 * 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}
 */
 
 const diameterOfBinaryTree = (root)=>{
     if(root == null) return 0;
     let dep = 1;
     const depNode = (node)=>{
         if(node == null) return 0
          let left = depNode(node.left)
          let right = depNode(node.right)
          dep = Math.max(dep,left + right + 1)
          return Math.max(left,right) + 1
     }
     depNode(root)
     return dep-1
 }

力扣102.二叉树的层序遍历


/**
 * 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}
 */
 
 const levelOrder = (root)=>{
    let res = [];
    if(root == null) return res
    let quene = [root];
    while(quene.length !== 0){
        let len = quene.length;
        let arr = [];
        for(let i=0;i<len;i++){
            let node = quene.shift();
            arr.push(node.val);
            node.left && quene.push(node.left);
            node.right && quene.push(node.right)
        }
        res.push(arr)
    }
    return res
 }

力扣108.将有序数组转换为二叉搜索树

/**
 * 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) {
const buildBST = (nums, start, end) => {
    if (start > end) { // 构成不了区间,返回null
      return null;
    }

    const midIndex = (start + end) >>>1; // 求中间索引
    const root = new TreeNode(nums[midIndex]); // 构建当前节点

    root.left = buildBST(nums, start, midIndex - 1); // 构建左子树
    root.right = buildBST(nums, midIndex + 1, end); // 构建右子树

    return root;
};


    return buildBST(nums,0,nums.length-1)
};

力扣98.验证二叉搜索树


/**
 * 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}
 */
 
 const isValidBST = (root)=>{
    let pre = null;
    
    const inOrder=(root)=>{
        if(root == null) return true;
        let left = inOrder(root.left);
        if(pre !== null && pre.val >=root.val) return false;
        pre = root;
        let right = inOrder(root.right)
        return left && right
    }
    return inOrder(root)
 }

力扣230.二叉搜索树第k小的元素

解题思路: 利用中序遍历,获取排序的数组,直接获取对应k位置值


/**
 * 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} k
 * @return {number}
 */
 
 const kthSmallest = (root,k)=>{
    const res = []; 
    const dfs = (root)=>{
        if(root == null) return null;
        dfs(root.left)
        res.push(root.val)
        dfs(root.right)
    }
    
    dfs(root)
    return res[k-1]
 }

力扣199.二叉树的右视图

解题思路:其实就是层序遍历的思想,只是每次循环需要去到添加的最后节点的val


/**
 * 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}
 */
 
 const rightSideView = (root)=>{
    let res = [];
    if(root == null) return res
    let quene = [root];
    while(quene.length !== 0){
        let len = quene.length;
        let curr = [];
        for(let i=0;i<len;i++){
            let node = quene.shift();
            curr.push(node.val);
            node.left && quene.push(node.left);
            node.right && quene.push(node.right)
        }
        res.push(curr.pop())
    }
    return res
 }

力扣114.二叉树展开为链表

/**
 * 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 {void} Do not return anything, modify root in-place instead.
 */
var flatten = function(root) {
        if(root == null) return null;
        
        flatten(root.left)
        flatten(root.right)

        let right = root.right;
        let left = root.left;
        root.right = left;
        root.left = null;
        //没搞明白 为什么要加这一步while
        while(root.right !== null){
            root = root.right
        }
        root.right = right        
};

力扣105.从前序和中序遍历序列构造二叉树

力扣437.路径总和III


/**
 * 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} targetSum
 * @return {number}
 */
var pathSum = function(root, targetSum) {
    let map = new Map();
    let res = 0;
    let dfs = (root,sum)=>{
        if(root == null) return 0;
        let target = sum + root.val;
        res += map.get(target-targetSum)|| 0
        // 记录路径的长度
        map.set(sum,(map.get(sum) || 0)+1)
        dfs(root.left,target)
        dfs(root.right,target)

        map.set(sum,map.get(sum)-1)
    }
    dfs(root,0)
    return res
};

力扣236.二叉树的最近公共祖先

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    if(root == null){
        return null;
    }
    if(root == p || root == q){
        return root;
    }

    const left = lowestCommonAncestor(root.left,p,q);
    const right = lowestCommonAncestor(root.right,p,q);

    if(left && right){
        return root;
    }
    if(!left){
        return right;
    }
    if(!right){
        return left;
    }
};

力扣124.二叉树中的最大路径和

/**
 * 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 maxPathSum = function(root) {
    let maxSum = 0; // 最大路径和

    const dfs = (root) => {
        if (root == null) { // 遍历到null节点,收益0
           return 0;
        }
        const left = dfs(root.left);   // 左子树提供的最大路径和
        const right = dfs(root.right); // 右子树提供的最大路径和

        const innerMaxSum = left + root.val + right; // 当前子树内部的最大路径和
        maxSum = Math.max(maxSum, innerMaxSum);      // 挑战最大纪录
        const outputMaxSum = root.val + Math.max(0, left, right); // 当前子树对外提供的最大和

        // 如果对外提供的路径和为负,直接返回0。否则正常返回
        return outputMaxSum < 0 ? 0 : outputMaxSum;

    };

    dfs(root);  // 递归的入口

    return maxSum; 

};