LeetCode100 二叉树个人题解

利用前序和中序数组构造二叉树

思路: 构造一颗二叉树一定要用递归+hash查找

  1. 找根 :从 preorder 中按prel拿出一个节点作为根。

  2. 切分 :拿着这个根的值,去 inorder 中找到它的位置 index。

    • 计算左子树的节点个数 = index - in_left(中序左边界)。
  3. 递归 :根据上面算出的节点个数,把 preorder 和 inorder 切分成左右两部分,分别递归构造左子树和右子树。

  4. 优化(关键) :因为每次都要在 inorder 中找根的位置,如果每次都用 for 循环找,时间复杂度会退化到 O(n2)O(n2)。我们可以用 HashMap 提前把 inorder 里"值 -> 下标"的映射存起来,这样找根的时间就变成了 O(1)O(1)。

/**

* 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;

* }

* }

*/

复制代码
       @param preorder 先序数组 
  • @param preL 当前子树在先序数组中的左边界
  • @param preR 当前子树在先序数组中的右边界
  • @param inL 当前子树在中序数组中的左边界
  • @param inR 当前子树在中序数组中的右边界

class Solution {

private Map<Integer,Integer> indexmap=new HashMap<>();

private TreeNode build(int\[\] preorder,int prel,int prer,int inl,int inr){

if(prer<prel||inl>inr)return null;

int rootval=preorderprel;

TreeNode root=new TreeNode(rootval);

int indexin=indexmap.get(rootval);

int leftsize=indexin-inl;

root.left=build(preorder,prel+1,prel+leftsize,inl,indexin-1);

root.right=build(preorder,prel+leftsize+1,prer,indexin+1,inr);

return root;

}

public TreeNode buildTree(int\[\] preorder, int\[\] inorder) {

int n=preorder.length;

for(int i=0;i<n;i++){

indexmap.put(inorderi,i);

}

return build(preorder,0,n-1,0,n-1);

}

}

树上求路径和为指定数的路径条数

思路:树上前缀+Hsah

  1. 前缀和定义 :从根节点走到当前节点的路径和记为 curSum。那么,如果存在某个祖先节点,从根走到那个祖先节点的路径和是 oldSum。

  2. 魔法公式 :如果 curSum - oldSum = targetSum,这就意味着从那个祖先节点到当前节点的这段路径和,刚好等于 targetSum。

    • 变形一下:oldSum = curSum - targetSum。
  3. 哈希表的作用 :我们在向下遍历的过程中,用一个 HashMap 记录当前路径上(从根到当前节点)所有前缀和出现的次数。

  4. 回溯(恢复现场) :当我们处理完一个节点的左右子树,准备返回它的父节点时,必须把当前节点的 curSum 从哈希表里减掉。因为当前节点已经不在我们要探索的下一条路径上了,不能影响其他分支的计算。

细节:

1.为避免树是单链表形式且结点值很大时导致前缀和溢出出现负数,map里的key前缀和要使用long类型

2.初始化:前缀和要先初始化map{0L,1};否则会出现漏掉

3.cursum是当前这条路径从根节点到当前节点的前缀和,当改变一条路径时,必须回溯

/**

* 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 dfs(TreeNode node,long cursum,int targetSum,Map<Long,Integer> premap){

if(node==null)return 0;

cursum+=node.val;

int count=premap.getOrDefault(cursum-targetSum,0);

premap.put(cursum,premap.getOrDefault(cursum,0)+1);

count+=dfs(node.left,cursum,targetSum,premap);

count+=dfs(node.right,cursum,targetSum,premap);

premap.put(cursum,premap.get(cursum)-1);

return count;

}

public int pathSum(TreeNode root, int targetSum) {

Map<Long,Integer> premap=new HashMap<>();

premap.put(0L,1);

return dfs(root,0L,targetSum,premap);

}

}

相关推荐
octopus_c1 小时前
C++ 模板详解:函数模板、类模板、特化与分离编译
开发语言·c++·算法
東隅已逝,桑榆非晚1 小时前
算法1. 双指针法-移动零
c++·算法
CQU_JIAKE2 小时前
11.1[A]
算法
文丑颜不良啊2 小时前
LeetCode1581~1600题目解析
java·leetcode
小郎君6582 小时前
(六)el-cascader 的展示值为什么不能直接 join:emitPath、路径还原与多选去重
vue.js·算法
郝学胜-神的一滴4 小时前
游戏设计:原型与开发 19:U3D工位布置与性格说明书
人工智能·算法·unity·unreal engine·游戏策划·游戏设计
hahaha60165 小时前
数字图像时域滤波或者3D降噪算法FPGA实现
算法·计算机视觉·fpga开发
文丑颜不良啊5 小时前
LeetCode1541~1560题目解析
java·leetcode
YSL0701245 小时前
一文通关-----树和二叉树
数据结构·算法