当前位置: 首页 > article >正文

代码随想录第十六天| 513.找树左下角的值 、112. 路径总和 、113. 路径总和 II、106、从中序与后序遍历序列构造二叉树

513. 找树左下角的值

题目描述

给定一个二叉树,找到树的最后一行最左边的节点值。

解题思路
  1. 深度优先遍历 (DFS):使用深度优先遍历来查找树的左下角值。
  2. 记录最大深度:定义 maxDepth 变量,用于记录遍历时的最大深度。
  3. 更新左下角节点值:在每次到达叶子节点时,判断当前深度是否大于 maxDepth,如果是,则更新 maxDepth 和结果 result,保存当前节点值为最左下角的节点值。
  4. 回溯:在递归中回溯深度值 depth,避免对其他分支的影响。
代码实现
class Solution {
	public int maxDepth = -1;
	int result;
    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>maxDepth){
				maxDepth = depth;
				result = root.val;
			}
		}
		if(root.left != null){
			depth++;
			traversal(root.left,depth);
			depth--;
		}
		if(root.right != null){
			depth++;
			traversal(root.right,depth);
			depth--;
		}
	}
}
  1. 路径总和

112. 路径总和

题目描述

给定一个二叉树和一个目标和 targetSum,判断该树中是否存在一条从根节点到叶子节点的路径,使得路径上所有节点值的和等于目标和。

解题思路
  1. 递归减去节点值:每次递归进入一个节点时,将当前节点值从 targetSum 中减去。
  2. 判断叶子节点:当到达叶子节点时,如果 targetSum 减到0,说明找到了符合条件的路径,返回 true
  3. 左右子树递归:如果当前节点不是叶子节点,递归地检查其左右子树是否存在满足条件的路径。
  4. 短路逻辑:在递归过程中,如果找到符合条件的路径,立即返回 true,否则最终返回 false
代码实现
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
		if (root == null) {
			return false;
		}
		targetSum -= root.val;
        if(root.left == null && root.right == null && targetSum ==0){
			return true;
		}
		if(root.left == null && root.right == null && targetSum !=0){
			return false;
		}
		if(root.left != null){
			boolean left = hasPathSum(root.left,targetSum);
			if(left)return left;
		}
		if(root.right != null){
			boolean right = hasPathSum(root.right,targetSum);
			if(right)return right;
		}
		return false;

    }
}

113. 路径总和 II

题目描述

给定二叉树的根节点 root 和一个整数目标和 targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。

解题思路
  1. 递归深度优先遍历:使用递归的深度优先搜索 (DFS) 来遍历二叉树,从根节点开始,到达叶子节点。
  2. 路径存储:在遍历的过程中使用 path 列表保存当前路径中的节点。
  3. 判断叶子节点:每当到达叶子节点时,判断当前路径总和是否等于 targetSum。如果满足条件,将当前路径的一个拷贝添加到结果 res 中。
  4. 回溯:每次递归返回上层节点时,移除 path 中的最后一个节点,确保在遍历其他路径时路径正确。
代码实现
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetsum) {
		List<List<Integer>> res = new ArrayList<List<Integer>>();
        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){
			if(targetsum-root.val==0){
				res.add(new ArrayList<>(path));
			}
			return;
		}
		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);
		}
	}
}

106. 从中序与后序遍历序列构造二叉树

题目:根据一棵树的中序遍历与后序遍历构造二叉树。

注意:你可以假设树中没有重复的元素。


解题思路

  1. 后序遍历的最后一个元素是树的根节点。
  2. 在中序遍历中找到根节点位置,从而分割出左右子树的中序序列。
  3. 根据左右子树的大小,在后序序列中划分出左右子树的后序序列。
  4. 递归构造左右子树,直至构造完成。

代码

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(postorder.length == 0 || inorder.length==0){
			return null;
		}
		return bulidHelper(inorder,0,inorder.length,postorder,0,postorder.length);

    }
	private TreeNode bulidHelper(int[] inorder, int inorderStart, int inorderEnd, int[] postorder, int postorderStart, int postorderEnd){
		if(postorderStart==postorderEnd){
			return null;
		}
		int rootVal = postorder[postorderEnd-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 leftpostorderStart = postorderStart;
		int leftpostorderEnd = postorderStart+middleIndex-inorderStart;

		int rightinorderStart = middleIndex+1;
		int rightinorderEnd = inorderEnd;
		int rightpostorderStart = postorderStart+middleIndex-inorderStart;
		int rightpostorderEnd = postorderEnd-1;
		root.left = bulidHelper(inorder,leftinorderStart,leftinorderEnd,postorder,leftpostorderStart,leftpostorderEnd);
		root.right = bulidHelper(inorder,rightinorderStart,rightinorderEnd,postorder,rightpostorderStart,rightpostorderEnd);
		return root;
	}

}

105.从前序与中序遍历序列构造二叉树

题目:根据一棵树的中序遍历与前序遍历构造二叉树。

注意:你可以假设树中没有重复的元素。


解题思路

  1. 后序遍历的最后一个元素是树的根节点。
  2. 在中序遍历中找到根节点位置,从而分割出左右子树的中序序列。
  3. 根据左右子树的大小,在后序序列中划分出左右子树的后序序列。
  4. 递归构造左右子树,直至构造完成。

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0 || inorder.length ==0){
			return null;
		}
		return helper(preorder,0,preorder.length, inorder,0,inorder.length);
    }
	private TreeNode helper(int[] preorder,int preorderstart,int preorderend, int[] inorder,int inorderstart,int inorderend){
		if(preorderstart == preorderend){
			return null;
		}
		int rootval = preorder[preorderstart];
		TreeNode root =new TreeNode(rootval);
		int midval;
		for(midval = inorderstart;midval<inorderend;midval++){
			if(inorder[midval]==rootval)
				break;
		}

		int leftpreorderstart = preorderstart+1;
		int leftpreorderend = preorderstart+midval-inorderstart+1;
		int leftinorderstart = inorderstart;
		int leftinorderend = midval;

		int rightpreorderstart = preorderstart+midval-inorderstart+1;
		int rightpreorderend = preorderend;
		int rightinorderstart = midval+1;
		int rightinorderend = inorderend;

		root.left = helper(preorder,leftpreorderstart,leftpreorderend, inorder,leftinorderstart,leftinorderend);
		root.right = helper(preorder,rightpreorderstart,rightpreorderend, inorder,rightinorderstart,rightinorderend);
		return root;

	}
}

http://www.kler.cn/a/386017.html

相关文章:

  • SpringBoot(5)-SpringSecurity
  • 插入排序——希尔排序
  • 【C++】string(一)
  • 31-Shard Allocation Awareness(机架感知)
  • 【Linux】系统中负责回收内存的进程和机制有哪些?
  • spring boot整合https协议
  • Rust性能优化与调试第二节:调试与错误处理的实用工具
  • 软件测试(系统测试)的定位和专业:完善产品;专业;非助手;自动化
  • FPGA图像处理.从认识噪声到去噪算法
  • 【服务器】使用命令行文本编辑器(如 vim、nano 或 vi)创建文件并编辑
  • JAVA设计模式之【建造者模式】
  • Java基于小程序公考学习平台的设计与实现(附源码,文档)
  • 大数据学习09之Hive基础
  • Beyond Compare 5 比较文本文件时,如何忽略字母的大小写差异?
  • docker入门(一)
  • unity显示获取 年月日周几【日期】
  • 关于Django 模型字段 `choices`自定义数据类型的枚举——补充
  • Java SPI——针对实习面试
  • 汽车和飞机研制过程中“骡车”和“铁鸟”
  • EL表达式和JSTL表达式(详解)
  • 【java】实战-力扣题库:移动零
  • Dubbo框架浅谈
  • 数字IC后端设计实现之Innovus自动修复Min Step DRC Violation方案
  • Agent指令编排
  • 双指针算法的妙用:提高代码效率的秘密(1)
  • ip地址跟路由器有关吗?更换路由器ip地址会变吗