Day18代码随想录
513.找树左下角的值
1.题目描述
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3]
输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
2.解题思路及代码实现
定义全局变量深度和value值,并采深度优先遍历,不断找深度最深的结点,无论前中后序遍历,总是优先遍历最左侧的结点,并判断深度
代码如下
class Solution {
int Depth = -1;
int result = 0;
public int findBottomLeftValue(TreeNode root) {
traversal(root,0);
return result;
}
public void traversal(TreeNode root,int depth){
if (root.left==null&&root.right==null){
if (depth>Depth){
Depth = depth;
result = root.val;
}
}
if (root.left!=null){
traversal(root.left,depth+1);
}
if (root.right!=null){
traversal(root.right,depth+1);
}
}
}
此题采用层序遍历也可以而且想也好想出来
112.路径总和
1.题目描述
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径
2.解题思路及代码实现
前序遍历,如果该几点为叶子结点并且,targetsum==0则存在一条路径符合要求,经过一个节点减去对应的val。并依次判断左子树和右子树是否有要求的路径
public class leetcode {
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;
}
}
113.路径总和II
1.题目描述
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
2.解题思路及代码实现
解法一:
遍历所有路径,并在叶子结点处判断路径上的所有val和是否为targetnum,在遍历完记得回溯
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> result = new ArrayList<>();
if (root==null) return result;
List<Integer> path = new ArrayList<>();
getPath(root,result,path,targetSum);
return result;
}
public void getPath(TreeNode root,List<List<Integer>> result,List<Integer> path,int targetSum){
path.add(root.val);
if (root.left==null&&root.right==null){
int count =0;
for(int num:path){
count+=num;
}
if (count==targetSum) {
result.add(new ArrayList<Integer>(path));
}
}
if (root.left!=null) {
getPath(root.left, result, path, targetSum);
path.remove(path.size()-1);
}
if (root.right!=null) {
getPath(root.right, result, path, targetSum);
path.remove(path.size()-1);
}
}
}
解法二
定义两个全局变量,并进行前序遍历处理这两个全局变量
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
travesal(root,targetSum);
return result;
}
public void travesal(TreeNode root,int count){
if (root==null) return;
count-=root.val;
path.add(root.val);
if (root.left==null&&root.right==null&&count==0)
result.add(new ArrayList<>(path));
travesal(root.left,count);
travesal(root.right,count);
path.remove(path.size()-1);//回溯
}
}
106.从中序与后序遍历序列构造二叉树
1.题目描述
给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历, postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
示例 2:
输入:inorder = [-1], postorder = [-1]
输出:[-1]
2.解题思路及代码实现
首先回忆一下如何根据两个顺序构造一个唯一的二叉树,相信理论知识大家应该都清楚,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。
如果让我们肉眼看两个序列,画一棵二叉树的话,应该分分钟都可以画出来。
流程如图:
那么代码应该怎么写呢?
说到一层一层切割,就应该想到了递归。
来看一下一共分几步:
- 第一步:如果数组大小为零的话,说明是空节点了。
- 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
- 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
- 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
- 第五步:切割后序数组,切成后序左数组和后序右数组
- 第六步:递归处理左区间和右区间
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 getNode(inorder,0,inorder.length,postorder,0,postorder.length);
}
public TreeNode getNode(int[] inorder,int inbegin,int inend,int[] postorder,int postbegin,int postend){
if(inbegin>=inend||postbegin>=postend){
return null;
}
int rootvalue = postorder[postend-1];
TreeNode root = new TreeNode(rootvalue);
int rootIndex = map.get(rootvalue);
int lenofLeft = rootIndex-inbegin;
root.left = getNode(inorder,inbegin,rootIndex,
postorder,postbegin,postbegin+lenofLeft);
root.right = getNode(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 < preorder.length; i++) {
map.put(inorder[i],i);
}
return getNode(preorder,0,preorder.length,inorder,0,inorder.length);
}
public TreeNode getNode(int[] preorder,int prebegin,int preend,int[] inorder,int inbegin,int inend){
if (prebegin>=preend||inbegin>=inend)
return null;
TreeNode root = new TreeNode();
int rootval = preorder[prebegin];
int Index = map.get(rootval);
int lenofLen = Index-inbegin;
root.val = rootval;
root.left = getNode(preorder,prebegin+1,prebegin+1+lenofLen,
inorder,inbegin,Index);
root.right = getNode(preorder,prebegin+1+lenofLen,preend,
inorder,Index+1,inend);
return root;
}
}