今日内容:513.找树左下角的值、112.路经总和、113.路经总和||、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树 代码随想录链接:代码随想录 (programmercarl.com)
513.找树左下角的值
给定一个二叉树的 根节点
root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。
找到最后一行然后返回最左边的值。
用层序遍历做,当最后一层的时候返回最左边的元素。找到最后一层,然后输出第一个。
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int res = root.val;
while(!queue.isEmpty()){
int len = queue.size();
List<Integer> list = new ArrayList<>();
while(len-- > 0){
TreeNode cur = queue.poll();
list.add(cur.val);
if(cur.left != null)queue.offer(cur.left);
if(cur.right != null)queue.offer(cur.right);
}
res = list.get(0);
}
return res;
}
}
这题取最后一行反而还方便了,到最后这个res队列保存的就是最后一行的值。这个时候返回第一个值就好了。
遍历法
用遍历的话,需要知道当前层是不是最后一层,因此需要传递深度。
class Solution {
public int depth = 0;
public int res;
public int findBottomLeftValue(TreeNode root) {
res = root.val;
find(root,0);
return res;
}
private void find(TreeNode root, int deep){
if(root == null)return;
if(deep > depth){
depth = deep;
res = root.val;
}
find(root.left, deep + 1);
find(root.right, deep + 1);
}
}
看了解析说可以迭代和递归,就都写出来了,好像没那么难?
112.路径总和
给你二叉树的根节点
root和一个表示目标和的整数targetSum。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum。如果存在,返回true;否则,返回false。
叶子节点 是指没有子节点的节点。
这题就和前面计算到叶子节点的最大深度题目一样了,不过现在这题用递归和迭代可能差不多,在遇到叶子节点的时候判定一下就好。
递归的话需要再传入一个当前节点值,和target值。
class Solution {
public boolean res = true;
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;
}
if(root.left != null){
boolean left = hasPathSum(root.left,targetSum);
if(left)return true;
}
if(root.right != null){
boolean right = hasPathSum(root.right,targetSum);
if(right)return true;
}
return false;
}
}
113.路径总和||
给你二叉树的根节点
root和一个整数目标和targetSum,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。
在上一题的基础上,改变输出形式即可。
class Solution {
List<List<Integer>> result;
LinkedList<Integer> path;
public List<List<Integer>> pathSum (TreeNode root,int targetSum) {
result = new LinkedList<>();
path = new LinkedList<>();
travesal(root, targetSum);
return result;
}
private void travesal(TreeNode root, int count) {
if (root == null) return;
path.offer(root.val);
count -= root.val;
if (root.left == null && root.right == null && count == 0) {
result.add(new LinkedList<>(path));
}
travesal(root.left, count);
travesal(root.right, count);
path.removeLast(); // 回溯
}
}
106.从中序与后序遍历序列构造二叉树
看一下一共分几步:
- 第一步:如果数组大小为零的话,说明是空节点了。
- 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
- 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
- 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
- 第五步:切割后序数组,切成后序左数组和后序右数组
- 第六步:递归处理左区间和右区间
class Solution {
Map<Integer, Integer> map;
public TreeNode buildTree(int[] inorder, int[] postorder) {
map = new HashMap<>();
for(int i = 0; i < inorder.length; i++){
map.put(inorder[i],i);
}
return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
public TreeNode findNode(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 = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenOfLeft);
root.right = findNode(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenOfLeft, postEnd - 1);
return root;
}
}
105.从前序与中序遍历序列构造二叉树
前序遍历的第一个节点在中序遍历座位分界点
class Solution {
Map<Integer, Integer> map;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return findNode(preorder, 0, preorder.length, inorder, 0, inorder.length);
}
public TreeNode findNode(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 = findNode(preorder, preBegin + 1, preBegin + lenOfLeft + 1,inorder, inBegin, rootIndex);
root.right = findNode(preorder, preBegin + lenOfLeft + 1, preEnd,inorder, rootIndex + 1, inEnd);
return root;
}
}
嘿嘿