513. 找树左下角的值
题目链接:513. 找树左下角的值 - 力扣(LeetCode)
讲解链接:代码随想录
求最后一行最后一个左子节点的值 就是求二叉树深度最大的叶子节点
递归:
- 确定递归函数的参数和返回值
参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。
本题还需要类里的两个全局变量,maxLen用来记录最大深度,result记录最大深度最左节点的数值。
代码如下:
int maxDepth = INT_MIN; // 全局变量 记录最大深度
int result; // 全局变量 最大深度最左节点的数值
void traversal(TreeNode* root, int depth)
2 .找到终止条件
当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
代码如下:
if (root->left == NULL && root->right == NULL) {
if (depth > maxDepth) {
maxDepth = depth; // 更新最大深度
result = root->val; // 最大深度最左面的数值
}
return;
}
3 .确定单层递归的逻辑
在找最大深度的时候,递归的过程中依然要使用回溯,代码如下:
// 中
if (root->left) { // 左
depth++; // 深度加一
traversal(root->left, depth);
depth--; // 回溯,深度减一
}
if (root->right) { // 右
depth++; // 深度加一
traversal(root->right, depth);
depth--; // 回溯,深度减一
}
return;
当然这道题其实用层序遍历更好做(队列迭代法) 只要找到深度最大的当然是用迭代好想
Java代码:
//递归
class Solution {
private int Deep = -1;
private int value = 0;
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);
}
}
//迭代
class Solution{
public int findBottomLeftValue(TreeNode root){
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int res = 0;
while(q.isEmpty()){
for(int i = 0; i < q.size(); i++){
TreeNode node = q.poll();
if(i == 0){
res = node.val;
}
if(node.left != null){
q.offer(node.left);
}
if(node.right != null){
q.offer(node.right);
}
}
}
return res;
}
}
112. 路径总和
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
Java代码:
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){
boolean left = hasPathSum(root.left, targetSum);
if (left) {
//已经找到 left为true
return true;
}
}
if(root.right != null){
boolean right = hasPathSum(root.right, targetSum);
if(right){
//已经找到
return true;
}
}
return false;
}
}
//迭代
class Solution{
public boolean hasPathSum(TreeNode root,int targetsum){
if(root == null) return false;
Stack<TreeNode> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
stack1.push(root);
stack2.push(root.val);
while(!stack1.isEmpty()){
for(int i = 0; i < stack1.size(); i++){
TreeNode node = stack1.pop();
int sum = stack2.pop();
//如果这个阶段是叶子结点 同时该节点的路径数值是sum 那就返回true
if(node.left == null && node.right == null && sum == targetsum){
return true;
}
//右节点 压进去一个节点的时候 把该节点的路径数字化也记录下来
if(node.right != null){
stack1.push(node.right);
stack2.push(sum + node.right.val);
}
//左节点 压进去一个节点的时候 把该节点的路径数值也记录下来
if(node.left != null){
stack1.push(node.left);
stack2.push(sum + node.left.val);
}
}
}
return false;
}
}
113 路径总和2
这道题要求输出等于sum的路径
Java代码;
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetsum) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
List<Integer> path = new LinkedList<>();
preorderdfs(root, targetsum, res, path);
return res;
}
public void preorderdfs(TreeNode root, int targetsum, List<List<Integer>> res, List<Integer> path){
path.add(root.val);
//遇到叶子结点
if(root.left == null && root.right == null){
//找到了和为targetsum的路径
if(targetsum - root.val == 0){
res.add(new ArrayList<>(path));
}
return;//如果和不为targetsum 返回
}
if(root.left != null){
preorderdfs(root.left, targetsum - root.val, res, path);
path.remove(path.size() - 1);//回溯
}
if(root.right != null){
preorderdfs(root.right, targetsum - root.val, res, path);
path.remove(path.size() - 1);//回溯
}
}
}
另一种递归解法比较简洁
Java代码:
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.从中序与后序遍历序列构造二叉树
题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
讲解链接:代码随想录
给定中序遍历和后序遍历的数组 构造二叉树
先找后序遍历的最后一个节点 一定是中序遍历的中间根节点 然后在其下标进行左右子树的分割查找 再递归
Java代码:
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);//放入中序遍历的键值对 前面是value 后面是key
}
//左闭右开
return findNode(inorder, 0, inorder.length, postorder,0,postorder.length);
//判断当前递归的是什么遍历 中序遍历 从0到其长度 后序遍历 从0到其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;
}
}
day16
标签:right,return,int,随想录,二叉树,左下角,null,root,left From: https://blog.csdn.net/chengooooooo/article/details/144427801