LeetCode - 513. Find Bottom Left Tree Value 找二叉树左下角的值
解题目标:找出二叉树最后一行最左边的值
解题思路:这道题的关键在于终止条件也就是遍历到叶子节点,判断当前深度是否是最大的,注意应当优先搜索左边的子树,如果先搜索右边子树,但实际左下角的值是存在于左子树中,那么结果就有可能停留在右子树了。
class Solution {
int maxDepth = Integer.MIN_VALUE;
int res = 0;
public int findBottomLeftValue(TreeNode root) {
traversal(root, 0);
return res;
}
public void traversal (TreeNode root, int curDepth) {
if (root.left == null && root.right == null) {
if (curDepth > maxDepth) {
maxDepth = curDepth;
res = root.val;
}
}
// left
if (root.left != null) {
traversal(root.left, curDepth + 1);
}
// right
if (root.right != null) {
traversal(root.right, curDepth + 1);
}
}
}
LeetCode - 112. Path Sum 路径总和
解题目标:给定一个二叉树和目标和,判断该树是否存在叶子节点到根节点的路径和等于目标和。
解题思路:递归题目先确定终止条件,终止条件除了根节点为空,其次就是叶子节点,在叶子节点判断叶子节点的值是否是targetSum,如果是的话就返回true。在询问左子树或右子树前先要用targetSum减去当前根节点的值,这样才能继续递归左子树或右子树,只要左或右能有一条是true即可。
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
// leaf node
if (root.left == null && root.right == null) {
return targetSum == root.val;
}
targetSum -= root.val;
if (root.left != null) {
if (hasPathSum(root.left, targetSum)) return true;
}
if (root.right != null) {
if (hasPathSum(root.right, targetSum)) return true;
}
return false;
}
}
LeetCode - 113. Path Sum II 路径总和 II
解题目标:给定一个二叉树和目标和,记录该树所有叶子节点到根节点的路径和等于目标和的情况。
解题思路:这道题和前一题类似,只不过最终要记录所有的path,因此需要一个helper function来帮助记录最终结果。这里注意在收集结果时path需要创建新对象来拷贝,因为path在回溯的时候是会变化的,如果不拷贝最后只有最后找到的一条路径。同时注意这里的targetSum在遍历左右子树前其实已经是隐式回溯了,因为这里减去root.val是传递给左或右子树的参数的,当前层需要用到targetSum的情况已经在这之前判断过了,因此不用显式地在遍历完左右子树后加回root.val来体现回溯。
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
findPaths(root, res, path, targetSum);
return res;
}
public void findPaths(TreeNode root, List<List<Integer>> res, List<Integer> path, int targetSum) {
if (root == null) return;
path.add(root.val);
if (root.left == null && root.right == null) {
if (root.val == targetSum) {
res.add(new ArrayList<>(path)); //需要拷贝当前路径,否则在回溯的时候会被修改
}
return;
}
targetSum -= root.val;
if (root.left != null) {
findPaths(root.left, res, path, targetSum);
path.remove(path.size() - 1);
}
if (root.right != null) {
findPaths(root.right, res, path, targetSum);
path.remove(path.size() - 1);
}
}
}
LeetCode - 106. Construct Binary Tree from Inorder and Postorder Traversal
解题思路:这道题可以从后序数组开始切入,后序的最后一个元素一定是该树的根节点,知道了根节点后可以在中序当中做切割,这样就可以分清哪些元素是左子树,哪些是右子树。知道了左右如何分割左右子树后,再回到后序数组按照中序数组切割后就可以找到左/右子树的根节点,再继续这样循环往复就可以构造出二叉树。