文章链接:代码随想录找树左下角的值 代码随想录路径总和 代码随想录从遍历序列构造二叉树
视频链接:代码随想录找树左下角的值 代码随想录路径总和 代码随想录从遍历序列构造二叉树
目录
代码随想录算法训练营第十八天 | LeetCode 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
1. LeetCode 513. 找树左下角的值
1.1 思路
1.2 代码
2. LeetCode 112. 路径总和 113. 路径总和 II
2.1 思路
2.2 代码
3. LeetCode 106. 从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树
3.1 思路
3.2 代码
// 递归法
class Solution {
private int Deep = -1;
private int value = 0;
public int findBottomLeftValue(TreeNode root) {
value = root.val;
findLeftValue(root,0);
return value;
}
private 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);
}
}
//112. 路径总和
class Solution {
private boolean traversal(TreeNode cur, int count) {
if (cur.left == null && cur.right == null && count == 0) return true; // 遇到叶子节点,并且计数为0
if (cur.left == null && cur.right == null) return false; // 遇到叶子节点直接返回
if (cur.left != null) { // 左
count -= cur.left.val; // 递归,处理节点;
if (traversal(cur.left, count)) return true;
count += cur.left.val; // 回溯,撤销处理结果
}
if (cur.right != null) { // 右
count -= cur.right.val; // 递归,处理节点;
if (traversal(cur.right, count)) return true;
count += cur.right.val; // 回溯,撤销处理结果
}
return false;
}
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) return false;
return traversal(root, sum - root.val);
}
}
//113. 路径总和 II
class Solution {
private List> result;
private List path;
private void traversal(TreeNode cur, int count) {
if (cur.left == null && cur.right == null && count == 0) { // 遇到了叶子节点且找到了和为sum的路径
result.add(new ArrayList<>(path));
return;
}
if (cur.left == null && cur.right == null) return; // 遇到叶子节点而没有找到合适的边,直接返回
if (cur.left != null) { // 左 (空节点不遍历)
path.add(cur.left.val);
count -= cur.left.val;
traversal(cur.left, count); // 递归
count += cur.left.val; // 回溯
path.remove(path.size() - 1); // 回溯
}
if (cur.right != null) { // 右 (空节点不遍历)
path.add(cur.right.val);
count -= cur.right.val;
traversal(cur.right, count); // 递归
count += cur.right.val; // 回溯
path.remove(path.size() - 1); // 回溯
}
}
public List> pathSum(TreeNode root, int sum) {
result = new ArrayList<>();
path = new ArrayList<>();
if (root == null) return result;
path.add(root.val); // 把根节点放进路径
traversal(root, sum - root.val);
return result;
}
}
//106.从中序与后序遍历序列构造二叉树
class Solution {
Map map; // 方便根据数值查找位置
public TreeNode buildTree(int[] inorder, int[] postorder) {
map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
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 map;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
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;
}
}