代码随想录算法训练营第二十一天 |找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树
今天第三个题,不太会🤪以后还得练习
今天的三个题都是使用递归进行做的。
找树左下角的值link
题目:给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
想法:递归
视频:link
class Solution {
//递归法
int DEEP = -1;
int value;
public int findBottomLeftValue(TreeNode root) {
value = root.val;
findLeftValue(root, 0);
return value;
}
public void findLeftValue(TreeNode root, int deep) {
//确认结束条件
if (root == null)
return;
//明确单层递归逻辑
if (root.left == null && root.right == null) {
if (deep > DEEP) {
value = root.val;
DEEP = deep;
}
}
if (root.left != null)
findLeftValue(root.left, deep + 1);
if (root.right != null)
findLeftValue(root.right, deep + 1);
}
}
路径总和link
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
注意的点:是找 根节点到叶子节点 的路径
文章推荐:link
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;
if (root.left != null) {
if (hasPathSum(root.left, targetSum))
return true;
}
if (root.right != null)
if (hasPathSum(root.right, targetSum))
return true;
return false;
}
}
从中序与后序遍历序列构造二叉树link
题目:给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
这道题对我而言有些难理解,以后还需要回顾。
递归:
第一步:如果数组大小为零的话,说明是空节点了。
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
第五步:切割后序数组,切成后序左数组和后序右数组
第六步:递归处理左区间和右区间
视频推荐:link
相关题目推荐(我也没写那,哈哈😂):link
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder.length == 0 || postorder.length == 0)
return null;
return getAns(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
// 递归法
// 注意采取的原则是:左闭右开!!!
TreeNode getAns(int[] inorder, int inorderStart, int inorderEnd, int[] postorder, int postorderStart,
int postorderEnd) {
// 结束条件//当后序数组为0时,结束
if (postorderStart == postorderEnd) {
return null;
}
int rootVal = postorder[postorderEnd - 1];// 后序遍历的最后一个值为根节点//注意:这里是[postorderEnd - 1]而不是[postorder.length-1]!!!
TreeNode root = new TreeNode(rootVal);
int middleIndex;
// 在中序遍历中寻找根节点的下标
for (middleIndex = inorderStart; middleIndex < inorderEnd; middleIndex++) {
if (inorder[middleIndex] == rootVal)
break;
}
// 对中序数组中的几个关键值进行标记:左子树的范围,右子树的范围
int leftInorderStart = inorderStart;
int leftInorderEnd = middleIndex;// 不要忘记喽 咱是左闭右开的区间!
int rightInorderStart = middleIndex + 1;
int rightInorderEnd = inorderEnd;
// 对后序数组进行标记
int leftPostorderStart = postorderStart;
int leftSize = middleIndex - inorderStart;// ??
int leftPostorderEnd = postorderStart + leftSize;
int rightPostorderStart = leftPostorderEnd;
int rightPostorderEnd = postorderEnd - 1;// 不要忘记喽 咱是左闭右开的区间!
root.left = getAns(inorder, leftInorderStart, leftInorderEnd, postorder, leftPostorderStart, leftPostorderEnd);
root.right = getAns(inorder, rightInorderStart, rightInorderEnd, postorder, rightPostorderStart,
rightPostorderEnd);
return root;
}
}
希望对您有一定的帮助,谢谢观看。