● 力扣题目链接
● 给定一个二叉树,在树的最后一行找到最左边的值。
● 层序遍历即可,每层不断更新res
● 递归有些难度,目标是找最大深度的叶子节点最左边的值
○ 最大深度,全局变量进行维护,一旦大就更新Deep
○ 叶子节点,一旦找到叶子节点,且是最大深度,更新值
○ 最左边,先左后右遍历,这样右边不会把左边覆盖
class Solution {
public int findBottomLeftValue(TreeNode root) {
Deque<TreeNode> queue = new ArrayDeque();
queue.addLast(root);
int res = 0;
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
if (size == 0) res = temp.val;
if (temp.right != null) queue.addLast(temp.right);
if (temp.left != null) queue.addLast(temp.left);
}
}
return res;
}
}
class Solution {
private int Deep = -1; // 维护最大深度
private int value = 0;
public int findBottomLeftValue(TreeNode root) {
value = root.val;
find(root, 0);
return value;
}
private void find(TreeNode root, int deep) {
if (root == null) return;
if (root.left == null && root.right == null) { // 叶子节点
if (deep > Deep) { // 深度更大
value = root.val; // 更新值
Deep = deep; // 更新深度
}
}
find(root.left, deep + 1); // 向左递归
find(root.right, deep + 1); // 向右递归
}
}
● 力扣题目链接
● 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
● 说明: 叶子节点是指没有子节点的节点。
● 如果为空,返回false,不为空,就减去val
● 然后本层逻辑是,一旦发现是叶子节点,直接比较
● 如果不是叶子节点,向左向右递归看
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
targetSum -= root.val;
if (root.left == null && root.right == null) {
return targetSum == 0;
}
return hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum);
}
}
class Solution {
int sum = 0;
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
sum += root.val;
if (root.left == null && root.right == null) {
sum -= root.val;
return targetSum == sum + root.val;
}
boolean res = hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum);
sum -= root.val;
return res;
}
}
● 有难度,后面再好好想想
class Solution {
List<List<Integer>> res = new ArrayList();
List<Integer> path = new ArrayList();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
find(root, targetSum);
return res;
}
private void find(TreeNode root, int targetSum) {
if (root == null) return;
path.add(root.val);
targetSum -= root.val;
if (root.left == null && root.right == null && targetSum == 0) {
res.add(new ArrayList<>(path));
}
find(root.left, targetSum);
find(root.right, targetSum);
path.remove(path.size() - 1);
}
}
● 力扣题目链接
● 根据一棵树的中序遍历与后序遍历构造二叉树。
● 注意: 你可以假设树中没有重复的元素。
● 边界条件处理需要注意,左闭右开处理
● 先根据后序数组,拆分中序数组,再拆分后序数组,递归
class Solution {
Map<Integer, Integer> map = new HashMap();
public TreeNode buildTree(int[] inorder, int[] postorder) {
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return find(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
private TreeNode find(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
if (inBegin >= inEnd || postBegin >= postEnd) return null;
int rootIndex = map.get(postorder[postEnd - 1]);
TreeNode root = new TreeNode(inorder[rootIndex]);
int lenOfLeft = rootIndex - inBegin;
root.left = find(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenOfLeft);
root.right = find(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenOfLeft, postEnd - 1);
return root;
}
}
● 和上题类似
class Solution {
Map<Integer, Integer> map = new HashMap();
public TreeNode buildTree(int[] preorder, int[] inorder) {
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return find(preorder, 0, preorder.length, inorder, 0, inorder.length);
}
private TreeNode find(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) {
if (preBegin >= preEnd || inBegin >= inEnd) return null;
int rootIndex = map.get(preorder[preBegin]);
TreeNode root = new TreeNode(inorder[rootIndex]);
int lenOfLeft = rootIndex - inBegin;
root.left = find(preorder, preBegin + 1, preBegin + lenOfLeft + 1, inorder, inBegin, rootIndex);
root.right = find(preorder, preBegin + lenOfLeft + 1, preEnd, inorder, rootIndex + 1, inEnd);
return root;
}
}