LeetCode刷题 Day18

59 阅读3分钟

LeetCode刷题 Day18

513. Find Bottom Left Tree Value

Given the root of a binary tree, return the leftmost value in the last row of the tree.

Example 1:

Input: root = [2,1,3]
Output: 1

Example 2:

Input: root = [1,2,3,4,null,5,6,null,null,7]
Output: 7

BFS法:

  • 每当在i === 0的时候更新leftResult

代码:

var findBottomLeftValue = function(root) {
    let queue = [];
    let leftResult = -1;
    
    queue.push(root);
    
    while (queue.length > 0) {
        const len = queue.length;
        for (let i = 0; i < len; i++) {
            const node = queue.shift();
            if (i === 0) leftResult = node.val;
            if (node.left) {
                queue.push(node.left);
            }   
            if (node.right) {
                queue.push(node.right);     
            }
        }       
    }

    return leftResult
};

DFS法:

  • 这个要理解遍历的顺序,当在遍历到末尾进行回溯的时候, 必然是先回到左边的节点 再去右边的节点,再结合最大的depth去判断最后一行最左边节点

代码:

var findBottomLeftValue = function(root) {
    let maxDepth = -1;
    let leftMostValue = -1;
    var helper = function(root, depth) {
        if (!root) return;
        if (!root.left && !root.right) {
            if (maxDepth < depth) {
                maxDepth = depth;
                leftMostValue = root.val;
            }
            return;
        }
        
        helper(root.left, depth + 1);
        helper(root.right, depth + 1);
    }
    
    helper(root, 0);
    
    return leftMostValue;
};

时间复杂度: O(n), 空间复杂度: O(n)


112. Path Sum

Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum.

leaf is a node with no children.

 

Example 1:

Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
Output: true
Explanation: The root-to-leaf path with the target sum is shown.

Example 2:

Input: root = [1,2,3], targetSum = 5
Output: false
Explanation: There two root-to-leaf paths in the tree:
(1 --> 2): The sum is 3.
(1 --> 3): The sum is 4.
There is no root-to-leaf path with sum = 5.

Example 3:

Input: root = [], targetSum = 0
Output: false
Explanation: Since the tree is empty, there are no root-to-leaf paths.

思路:

  • 这道题的重点在于 !root的时候应该false, 根据 example 3的描述
  • 用“隐藏式”的回溯比较方便

代码:

var hasPathSum = function(root, targetSum) {
    if (!root) return false;
    if (!root.left && !root.right && targetSum === root.val) return true;
    
    return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val)
};

时间复杂度: O(n),还是把节点都遍历一遍 空间复杂度: O(n)


113. Path Sum II

Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where the sum of the node values in the path equals targetSum . Each path should be returned as a list of the node values, not node references.

root-to-leaf path is a path starting from the root and ending at any leaf node. A leaf is a node with no children.

  Example 1:

Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
Output: [[5,4,11,2],[5,8,4,5]]
Explanation: There are two paths whose sum equals targetSum:
5 + 4 + 11 + 2 = 22
5 + 8 + 4 + 5 = 22

Example 2:

Input: root = [1,2,3], targetSum = 5
Output: []

Example 3:

Input: root = [1,2], targetSum = 0
Output: []

思路:

  • 这个和 Path SumI是一样的,但是要记录path, 所以将path作为参数放入递归中, 当符合条件的时候就res.push([...path])

代码:

var pathSum = function(root, targetSum) {
    let res = [];
    
    var helper = function(root, path, targetSum) {
        if (!root) return;
        if (!root.left && !root.right) {
            if (root.val === targetSum) {
                path.push(root.val);
                res.push([...path]);
                path.pop();
                return;
            }
        }
        
        path.push(root.val);
        helper(root.left, path, targetSum - root.val);
        helper(root.right, path, targetSum - root.val);
        path.pop();
    }
    
    helper(root, [], targetSum);
    return res;
};

时间复杂度: O(n2), 这里要考虑deep copy的问题,复杂度是O(n),再结合树本身的遍历O(n)。最后应该是O(n2) 空间复杂度: O(n)


105. Construct Binary Tree from Preorder and Inorder Traversal

Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct and return the binary tree.

Example 1:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

Example 2:

Input: preorder = [-1], inorder = [-1]
Output: [-1]

思路:

  • 有点像二分搜索, 但是left和right是用来定位inorder的左右区间
  • prorder可以以从左到右的顺序获得根节点的value,通过根节点的value在inorder中进行定位,将二叉树分为左右两支。 再在左右两支中继续相同逻辑,直到left > right,return null

代码:

var buildTree = function(preorder, inorder) {
    var helper = function (left, right) {
        if (left > right) return null;
        const rootVal = preorder.shift();
        const root = new TreeNode(rootVal);
        
        root.left = helper(left, inorder.indexOf(rootVal) - 1);
        root.right = helper(inorder.indexOf(rootVal) + 1, right);
        return root;
    }
    
    return helper(0, inorder.length - 1);
};

时间复杂度: O(n) 空间复杂度: O(n)


106. Construct Binary Tree from Inorder and Postorder Traversal

Given two integer arrays inorder and postorder where inorder is the inorder traversal of a binary tree and postorder is the postorder traversal of the same tree, construct and return the binary tree.

Example 1:

Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
Output: [3,9,20,null,null,15,7]

Example 2:

Input: inorder = [-1], postorder = [-1]
Output: [-1]

思路:

  • 和105题一样, 不同的是要注意后序遍历的顺序和先序遍历是反的。
var buildTree = function(inorder, postorder) {
    var helper = function(left, right) {
        if (left > right) return null;
        const rootVal = postorder.pop();
        const root = new TreeNode(rootVal);
        root.right = helper(inorder.indexOf(rootVal) + 1, right);
        root.left = helper(left, inorder.indexOf(rootVal) - 1);
        return root;
    }
    
    return helper(0, inorder.length - 1);
};

时间复杂度: O(n) 空间复杂度: O(n)