一、513.找树左下角的值
题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/
文章讲解:https://programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
1.1 初见思路
- 层序遍历,最后一行的第一个元素就是要找的值
- 怎么知道到了最后一层:每层都更新一遍最左的元素值,没有再有下一层的时候就说明到最后一层了
1.2 具体实现
class Solution {
int leftVal=0;
public int findBottomLeftValue(TreeNode root) {
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int res = 0;
while(!queue.isEmpty()){
int size = queue.size();
for(int i=0;i<size;i++){
TreeNode node = queue.poll();
if(i==0){
res=node.val;
}
if(node.left!=null){
queue.offer(node.left);
}
if(node.right!=null){
queue.offer(node.right);
}
}
}
return res;
}
}
1.3 重难点
二、112. 路径总和
题目链接:https://leetcode.cn/problems/path-sum/
文章讲解:https://programmercarl.com/0112.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C.html
视频讲解:https://www.bilibili.com/video/BV19t4y1L7CR
2.1 初见思路
- 递归+回溯
- 剪枝,当算出总和已经大于target了,这条分支的剩余计算都不用做了
2.2 具体实现
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
return hasSum(root, targetSum);
}
public boolean hasSum(TreeNode node, int target) {
target -= node.val;
if (node.left == null && node.right == null) {
if (target == 0) {
return true;
}
return false;
}
if (node.left != null) {
boolean leftFlag = hasSum(node.left, target);
if (leftFlag) {
return true;
}
}
if (node.right != null) {
boolean rightFlag = hasSum(node.right, target);
if (rightFlag) {
return true;
}
}
return false;
}
}
2.3 重难点
三、 106.从中序与后序遍历序列构造二叉树
题目链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
文章讲解:https://programmercarl.com/0106.%E4%BB%8E%E4%B8%AD%E5%BA%8F%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91.html
视频讲解:https://www.bilibili.com/video/BV1vW4y1i7dn
3.1 初见思路
- 中序:左中右,后续:左右中
- 先用后序遍历找到根节点,再去中序中进行分割
3.2 具体实现
class Solution {
HashMap<Integer,Integer> inorderArrayMap = new HashMap<>();
int[] post;
public TreeNode buildTree(int[] inorder, int[] postorder) {
for(int i = 0;i < inorder.length; i++) {
inorderArrayMap.put(inorder[i], i);//妙啊!将节点值及索引全部记录在哈希表中
}
post = postorder;
TreeNode root = buildTree(0, inorder.length - 1, 0, post.length - 1);
return root;
}
public TreeNode buildTree(int inorderStart, int inorderEnd, int postorderStart, int postorderEnd) {
if(inorderEnd < inorderStart || postorderEnd < postorderStart) return null;
int root = post[postorderEnd];//根据后序遍历结果,取得根节点
int rootIndexInInorderArray = inorderArrayMap.get(root);//获取对应的索引
TreeNode node = new TreeNode(root);//创建该节点
node.left = buildTree(inorderStart, rootIndexInInorderArray - 1, postorderStart, postorderStart + rootIndexInInorderArray - inorderStart - 1);
node.right = buildTree(rootIndexInInorderArray + 1, inorderEnd, postorderStart + rootIndexInInorderArray - inorderStart, postorderEnd - 1);
return node;//注意!返回的是新建的node!
}
}
3.3 重难点
- 思路不难,实现有难度
- 把中序遍历的值和下标存储在map中;这样能在后序遍历找到中节点后快速找到对应的在中序遍历中的下标