算法刷题——二叉树

673 阅读5分钟

100 相同的树

leetcode-cn.com/problems/sa…

递归解法


/**
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {boolean}
 */
var isSameTree = function(p, q) {
    if(p === null || q === null ){
        if(p === null && q === null)
            return true;
        else
            return false;
    }

    if(p.val !== q.val)
        return false;
    
    let left = isSameTree(p.left,q.left);
    let right = isSameTree(p.right,q.right);
    if(left && right)
        return true;
    else
        return false;
};

BFS解法

/**
 * 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} p
 * @param {TreeNode} q
 * @return {boolean}
 */
var isSameTree = function(p, q) {
   let queue1 = [p];
   let queue2 = [q];

   while(queue1.length){
       let node1 = queue1.shift();
       let node2 = queue2.shift();

       if(!node1 || !node2){
           if(node1 !== node2)
                return false;
            else
                continue;//如果都为空则继续shift
       }
       if(node1.val != node2.val) return false;
       queue1.push(node1.left);
       queue1.push(node1.right);
       queue2.push(node2.left);
       queue2.push(node2.right);
   }
   return true;
};

113 路径总和

/**
	DFS
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {number[][]}
 */
var pathSum = function(root, targetSum) {
    let res = [];

    const dfs = (root,sum,temp) =>{
        if(!root)
            return;
        temp.push(root.val);
        sum += root.val;
        if(!root.left && !root.right){
            if(sum === targetSum)
                res.push(temp.slice());//深拷贝数组
        }
        if(root.left)
            dfs(root.left,sum,temp);
        if(root.right)
            dfs(root.right,sum,temp);

        temp.pop();//回溯
        return;
    }

    dfs(root,0,[]);
    return res;
};

112 路径总和

/**
	DFS(第一版) 记录每一条路径的值,到叶节点就求和比较
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
    
    let temp = [];
    let flag = false;

    function dfs(root){
        if(!root)//如果为空
            return;
        temp.push(root.val);//入栈

        if(!root.left && !root.right){
            let sum = temp.reduce((pre,cur)=>{return pre + cur})
            if(sum === targetSum)
                flag = true;
        }
        dfs(root.left);
        dfs(root.right);
        temp.pop();//回溯出栈
    }
    dfs(root);

    return flag;
};
/**
DFS 每一层都变化targetsum
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
    if(!root){
            return false;
    }
    if(!root.left && !root.right){
        if(root.val === targetSum)
            return true;
        else
            return false;
    }
    
    let left = hasPathSum(root.left, targetSum - root.val);
    if(left) return true;
    let right = hasPathSum(root.right, targetSum - root.val);
    if(right) return true;
    return false;
};

257 二叉树的所有路径

/**
DFS
 */
/**
 * @param {TreeNode} root
 * @return {string[]}
 */
var binaryTreePaths = function(root) {
    if(!root)
        return [];
    let res = [];

    function dfs(root,str){
        let oldStr = str;//记录原来的值以便回溯
        if(!root)
            return;
        if(!root.left && !root.right){//叶节点就只拼接数
            str += root.val;
            res.push(str);
            return;
        }
        let temp = root.val +'->';//中间节点要加一个->
        str += temp;

        dfs(root.left,str);
        dfs(root.right,str);
        str = oldStr;//回溯
        return;     
    }
    dfs(root,"")
    return res;

};

129求根到叶子节点数字之和

/**
DFS
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var sumNumbers = function(root) {
    if(!root)
        return 0;
    let res = [];
     function dfs(root,str){
        if(!root)
            return;
        let oldStr = str;
        str += String(root.val);
        if(!root.left && !root.right){
            res.push(Number(str));
            return;
        }

        dfs(root.left,str);
        dfs(root.right,str);

        str = oldStr;
        return;
     }
     dfs(root,"");
     return res.reduce((total,cur)=>{return total + cur});
    
};

437 路径总和(不一定是从根到叶)***

leetcode-cn.com/problems/pa…

/**
	dfs + 递归
 */
/**
 * @param {TreeNode} root
 * @param {number} sum
 * @return {number}
 */
var pathSum = function(root, sum) {
    if(!root)
        return 0;
    function dfs(root,tempSum){
        if(!root)
            return 0;
        tempSum += root.val;

        let l = dfs(root.left,tempSum);
        let r = dfs(root.right,tempSum);
        //如果到该节点就是一个合法路径那就再加一
        return l + r + (tempSum === sum ? 1 : 0);
    }
    //从根节点出发的条数   从左子树出发的条数    从右子树出发的条数
    return dfs(root,0) + pathSum(root.left,sum) + pathSum(root.right,sum);

};

102 二叉树的层次遍历

leetcode-cn.com/problems/bi…

/**
	BFS
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
    let res = [];
    if(!root)
        return res;
    let queue = [root];
    while(queue.length){
        let length = queue.length;
        let temp = [];
        while(length--){
            let top = queue.shift();
            temp.push(top.val);
            if(top.left){
                queue.push(top.left);
            }
            if(top.right){
                queue.push(top.right);
            }
        }
        res.push(temp);
    }
    return res;
};
/**
	Dfs
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
    let res = [];
    const dfs = (root,level) =>{
        if(!root)
            return;
            
        if(!res[level])
            res.push([]);
        res[level].push(root.val);

        dfs(root.left,level + 1);
        dfs(root.right,level + 1);
    }
    dfs(root,0);
    return res;
};

144 二叉树的前序遍历

leetcode-cn.com/problems/bi…

/**
 DFS
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    let res = [];

    let dfs = (root) =>{
        if(!root)
            return;
        res.push(root.val);
        dfs(root.left);
        dfs(root.right);
        return;
    }
    
    dfs(root);
    return res;
};
/**
DFS 迭代
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    
    let res = [];
    if(!root)
        return res;
    let stack = [root];
    while(stack.length){
        let len = stack.length;
        while(len--){
            let now = stack.pop();
            res.push(now.val);
            if(now.right) stack.push(now.right);
            if(now.left) stack.push(now.left);//为了出栈时献出左节点,所以入栈时后入
        }

    }
    return res;
};

199 二叉树的右视图

/**
BFS
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var rightSideView = function(root) {
    let res = [];
    if(!root)
        return res;
    let queue = [root];
    while(queue.length){
        let len = queue.length;
        let temp = [];
        let top;
        while(len--){
            top = queue.shift();
            if(top.left) queue.push(top.left);
            if(top.right) queue.push(top.right);
        }
        res.push(top.val);
    }
    return res;
};

104 二叉树的最大深度

leetcode-cn.com/problems/ma…

/**
DFS 递归
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    let max = 0;
    let dfs = (root,level) =>{
        if(!root)
            return;
        if(!root.left && !root.right){
            max = max > level ? max : level;
        }
        dfs(root.left,level + 1);
        dfs(root.right,level + 1);
        return;
    }
    dfs(root,1);
    return max;
};
/**
	bfs	
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    if(!root)
        return 0;
    let queue = [root];
    let level = 0;
    while(queue.length){
        level++;
        let len = queue.length;
        while(len--){
            let top = queue.shift();
            if(top.left) queue.push(top.left);
            if(top.right) queue.push(top.right);
        }
    }
    return level;
};

111 二叉树的最小深度

/**
	DFS 递归 
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var minDepth = function(root) {
    let min = Infinity;
    if(!root)
        return 0;
    let dfs = (root,level) =>{
        if(!root)
            return;
        if(!root.left && !root.right){
            min = Math.min(min,level);
            return;
        }
        dfs(root.left,level+1);
        dfs(root.right,level+1);
        return;
    }
    dfs(root,1);
    return min;
};
/**
	bfs	
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var minDepth = function(root) {
    if(!root)
        return 0;
    let queue = [root];
    let depth = 0;
    while(queue.length){
        depth++;
        let len = queue.length;
        while(len--){
            let node = queue.shift();
            let left = node.left;
            let right = node.right;
            if(!left && !right)
                return depth;//层次遍历遇到叶节点就直接返回 不用遍历整个树
            if(left)
                queue.push(left);
            if(right)
                queue.push(right);
        }
    }
    return depth;

};

101 对称的二叉树

leetcode-cn.com/problems/sy…

/**
 递归
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isSymmetric = function(root) {
    if(!root)
        return true;
    //一个递归函数 
    function isSame(root1,root2){
        if(!root1 && !root2)//两个都为空
            return true;
        if(!root1 || !root2 || root1.val!== root2.val)//一个为空或者值不相等
            return false;
        let a = isSame(root1.left,root2.right);//判断左子树的左边和右子树的右边是否一样
        let b = isSame(root1.right,root2.left);//判断左子树的右边和右子树的左边是否一样
        if(a && b)
            return true;
        return false;
    }
    return isSame(root.left,root.right);
};
/**
	BFS
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isSymmetric = function(root) {
    if(!root)
        return true;
    let queue = [root];

    while(queue.length){
        let len = queue.length;
        let temp = [];
        while(len--){
            let node = queue.shift();
            if(!node)
                temp.push(null);
            else{
                temp.push(node.val);
                queue.push(node.left);
                queue.push(node.right);
            }
        }
        //双指针法判断是不是回文数组
        let left = 0;
        let right = temp.length - 1;
        while(left <= right){
            if(temp[left]!==temp[right])
                return false;
            left++;
            right--;
        }

    }
    return true;
 
};

110 平衡二叉树

leetcode-cn.com/problems/ba…

/**
DFS 递归
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    let flag = true;

    function height(root){//这个函数可以获得树的高度
        if(!root)
            return 0;
        let left = height(root.left);
        let right = height(root.right);
        
        if(Math.abs(left - right) > 1)//如果不平衡就flag=false
            flag = false;
        return Math.max(left,right) + 1;
    }

    height(root);
    return flag;
};

404 左叶子之和

leetcode-cn.com/problems/su…

/**
DFS
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var sumOfLeftLeaves = function(root,isLeft = false) {
    if(!root)
        return 0;
    if(!root.left && !root.right && isLeft){
        return root.val;
    }
    return sumOfLeftLeaves(root.left,true) + sumOfLeftLeaves(root.right,false);
};

236 二叉树的最近公共祖先 ***

/**
DFS
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    if(!root)
        return null;
    if(root === p || root === q)
        return root;
    let l = lowestCommonAncestor(root.left,p,q);//在左子树是否有p q
    let r = lowestCommonAncestor(root.right,p,q);
	//肯定至少有一个不为Null
    if(l && r)
        return root;
    if(!l)
        return r;
    return l;
        
};

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) {
    if(nums.length === 0)
        return null;

    let left = 0;
    let right = nums.length;
    let mid = (left + right) >> 1;
    
    let root = new TreeNode(nums[mid]);
    root.left = sortedArrayToBST(nums.slice(left,mid));
    root.right = sortedArrayToBST(nums.slice(mid + 1, right));

    return root;
    
    
};

450 删除二叉搜索树的节点

leetcode-cn.com/problems/de…

/**
 * 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} key
 * @return {TreeNode}
 */
var deleteNode = function(root, key) {
    if(!root)
        return null;
    if(root.val !== key){
        if(root.val > key)
            root.left = deleteNode(root.left, key);
        else
            root.right = deleteNode(root.right, key);
        return root;
    }
    //该节点就是要删除的节点

    //叶节点直接返回
    if(!root.left && !root.right) return null;
    //只有一个子树
    if(!root.left) return root.right;
    if(!root.right) return root.left;

    //有两个子树  就把右节点接到左子树的最右节点 返回左子树
    let leftNode = root.left;
    while(leftNode.right){
        leftNode = leftNode.right;
    }
    leftNode.right = root.right;
    return root.left;
};