Day28——二叉树专题 我会带着你远行 2024-04-01 15:05 64阅读 0赞 #### 文章目录 #### * * * * 14.路径总和I * 15.路径总和II * 16.路径总和III * 17.从中序与后序遍历序列构造二叉树 * 18. 从前序与中序遍历序列构造二叉树 -------------------- ##### 14.路径总和I ##### **思路**:`dfs`从根节点遍历到叶子节点,判断这条路径是否符合要求即可。 class Solution { public boolean hasPathSum(TreeNode root, int targetSum) { return dfs(root,targetSum); } public boolean dfs(TreeNode root,int targetSum){ if(root==null){ return false; } if(root.left==null&&root.right==null){ return targetSum==root.val; } return dfs(root.left,targetSum-root.val)||dfs(root.right,targetSum-root.val); } } ##### 15.路径总和II ##### **思路**:`dfs` 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); // 回溯 } } } **解法二**:迭代法 // 解法2 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(); // 回溯 } } ##### 16.路径总和III ##### **双重`DFS`**:我们遍历每一个节点,从这个节点开始计算它的子树满足要求的路径。 我们访问每一个节点 node,检测以node 为起始节点(头节点)且向下延深的路径有多少种(第二次`dfs`判断左右子树是否右满足的情况)。我们递归遍历每一个节点的所有可能的路径,然后将这些路径数目加起来即为返回结果。 class Solution { int res = 0; public int pathSum(TreeNode root, int targetSum) { if(root == null){ return 0; } long longTargetSum = targetSum; dfs(root, longTargetSum);// 每一个根节点都要dfs判断 // 为下一次dfs做好准备 pathSum(root.left, targetSum); pathSum(root.right, targetSum); return res; } public void dfs(TreeNode root, long sum){ if(root == null){ return ; } sum -= root.val; if(sum == 0){ rse ++; // 这里不能return !! 下面可能还要答案集 } dfs(root.left, sum); dfs(root.right, sum); } } ##### 17.从中序与后序遍历序列构造二叉树 ##### 题目链接:[106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)][106. _ - _LeetCode] **思路**: * 第一步:如果数组大小为零的话,说明是空节点了。 * 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。 * 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点 * 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组) * 第五步:切割后序数组,切成后序左数组和后序右数组 * 第六步:递归处理左区间和右区间 **代码实现**: 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; } } ##### 18. 从前序与中序遍历序列构造二叉树 ##### **题目链接**:[105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)][105. _ - _LeetCode] 思路看上一题即可 **代码实现**: 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; } } [106. _ - _LeetCode]: https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ [105. _ - _LeetCode]: https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
相关 Day30——二叉树专题 文章目录 22.验证二叉搜索树 23.二叉搜索树的最小绝对差 24.二叉搜索树中的插入 谁借莪1个温暖的怀抱¢/ 2024年04月01日 15:23/ 0 赞/ 62 阅读
还没有评论,来说两句吧...