给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
层序遍历,只不过是右边的节点先入队,所以最后的就是左边节点的值。
class Solution {
public int findBottomLeftValue(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
int res = 0;
while (!deque.isEmpty()) {
int size = deque.size();
for (int i = 0; i < size; i++) {
TreeNode curr = deque.poll();
if (curr.right != null) {
deque.offer(curr.right);
}
if (curr.left != null) {
deque.offer(curr.left);
}
res = curr.val;
}
}
return res;
}
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
以targetSum为初始值,遍历到哪个节点减去它的值,如果到叶节点sum和叶节点的值相同,那么就有这样的路径
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
if (root.left == null && root.right == null) {
return root.val == targetSum;
}
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
使用两个队列,分别存储将要遍历的节点,以及根节点到这些节点的路径和。注意在while循环内部就不用遍历了。
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
Deque<TreeNode> deque = new LinkedList<>();
Deque<Integer> dequeVal = new LinkedList<>();
deque.offer(root);
dequeVal.offer(root.val);
while (!deque.isEmpty()) {
TreeNode curr = deque.poll();
int temp = dequeVal.poll();
if (curr.left == null && curr.right == null) {
if (temp == targetSum) {
return true;
}
continue;
}
if (curr.left != null) {
deque.offer(curr.left);
dequeVal.offer(curr.left.val + temp);
}
if (curr.right != null) {
deque.offer(curr.right);
dequeVal.offer(curr.right.val + temp);
}
}
return false;
}
}
就是在上一题的基础上把路径输出。
使用path(队列,感觉也可以用ArrayList)存储路径。dfs从node开始,分左右子节点向下寻找。如果这个节点访问完,那么就把这个节点从队列中移除,再去另一边寻找(所以需要出队操作)。
class Solution {
List<List<Integer>> res = new LinkedList<List<Integer>>();
Deque<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
dfs(root, targetSum);
return res;
}
public void dfs(TreeNode node, int sum) {
if (node == null) {
return;
}
path.offer(node.val);
if (node.left == null && node.right == null && node.val == sum) {
res.add(new LinkedList<Integer>(path));
}
dfs(node.left, sum - node.val);
dfs(node.right, sum - node.val);
path.pollLast();
}
}
核心思路
1.后序遍历特性:postorder 的最后一个元素是当前子树的根节点。
2.中序遍历分割:找到根节点在中序遍历 inorder 中的位置,左侧为左子树,右侧为右子树。
3.递归构造:根据根节点分割中序和后序数组,分别构造左子树和右子树。
class Solution {
int[] inorder;
int[] postorder;
Map<Integer, Integer> map_idx = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.inorder = inorder;
this.postorder = postorder;
int len = inorder.length - 1;
for (int i = 0; i <= len; i++) {
map_idx.put(inorder[i], i);
}
return build(0, len, 0, len);
}
public TreeNode build(int inleft, int inright, int postleft, int postright) {
if (inleft > inright || postleft > postright) {
return null;
}
// 后序遍历的最后一个元素是根节点
int rootVal = postorder[postright];
TreeNode root = new TreeNode(rootVal);
// 在中序中找到根节点的索引
int rootIndex = map_idx.get(rootVal);
int leftNodeCount = rootIndex - inleft;
// 递归构造左子树和右子树
root.left = build(inleft, rootIndex - 1, postleft, postleft + leftNodeCount - 1);
root.right = build(rootIndex + 1, inright, postleft + leftNodeCount, postright - 1);
return root;
}
}
和前面的一样,改一下前序序列的起始点就可以了
class Solution {
int[] preorder;
int[] inorder;
Map<Integer, Integer> map_idx = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.inorder = inorder;
this.preorder = preorder;
int len = inorder.length - 1;
for (int i = 0; i <= len; i++) {
map_idx.put(inorder[i], i);
}
return build(0, len, 0, len);
}
public TreeNode build(int inleft, int inright, int preleft, int preright) {
if (inleft > inright || preleft > preright) {
return null;
}
// 前序遍历的第一个节点是根节点
int rootVal = preorder[preleft];
TreeNode root = new TreeNode(rootVal);
// 在中序遍历中找到根节点
int rootIndex = map_idx.get(rootVal);
int leftNodeCount = rootIndex - inleft;
root.left = build(inleft, rootIndex - 1, preleft + 1, preleft + 1 + leftNodeCount);
root.right = build(rootIndex + 1, inright, preleft + 1 + leftNodeCount, preright);
return root;
}
}