目录
参考链接:代码随想录
112.路径总和
题目:
给你二叉树的根节点
root
和一个表示目标和的整数targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和targetSum
。如果存在,返回true
;否则,返回false
。叶子节点 是指没有子节点的节点。
题解:
需要二叉树的根节点和计数器,计数器用来计算二叉树的一条边之和是否正好是目标和。
计数器如何统计这一条路径的和?
让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。如果最后count==0,同时到了叶子节点的话,说明找到了目标和。如果遍历到了叶子节点,count不为0,就是没找到。
注意:在进入当前节点时,已经执行了 targetSum -= root.val,所以这里的 targetSum 实际上是原始目标值减去路径上所有节点值(包括当前叶子节点)后的剩余值,如果剩余值 targetSum 为0,说明从根节点到当前叶子节点的路径和恰好等于原始目标值,返回 true。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
targetSum-=root.val;
//在叶子节点处,我们检查此时的 targetSum 是否为0
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;
}
}
}
}
513.找树左下角的值
链接:513. 找树左下角的值 - 力扣(LeetCode)
题目:
给定一个二叉树的 根节点
root
,请找出该二叉树的 最底层 最左边 节点的值。假设二叉树中至少有一个节点。
题解:
1.参数必须有要遍历的树的根节点,还有一个int型的变量来记录最长深度。
2.需要两个全局变量,Deep用来记录最大深度,value记录最大深度最左节点的数值。
3.当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
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);
}
}
106.从中序与后序遍历序列构造二叉树
链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
题目:给定两个整数数组
inorder
和postorder
,其中inorder
是二叉树的中序遍历,postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
题解:
中序:左中右
后序:左右中
后序的最后一个元素一定是根节点,然后根据中序,确定左区间和右区间里面的元素,再根据左,右区间里面的元素反过来又去切割后序数组。
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保存中序序列的数值对应位置
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.从前序与中序遍历序列构造二叉树
链接:105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
题目:给定两个整数数组
preorder
和inorder
,其中preorder
是二叉树的先序遍历,inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
题解:
前序:中左右
中序:左中右
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
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保存中序序列的数值对应位置
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;
}
}