2024.2.22
- 题目来源
- 我的题解
- 方法一 分治思想
题目来源
力扣每日一题;题序:889
我的题解
方法一 分治思想
题解参考:官方题解
令 nn为二叉树的节点数目,那么根据前序遍历与后序遍历的定义,preorder[0] 与 postorder[n−1] 都对应二叉树的根节点。获取根节点后,需要划分根节点的左子树与右子树,考虑两种情况:
- 原二叉树的根节点的左子树不为空,那么 preorder[1]对应左子树的根节点
- 原二叉树的根节点的左子树为空,那么 preorder[1] 对应右子树的根节点。
对于以上两种情况,无法区分 preorder[1]到底是哪种情况。但是对于第二种情况,将原二叉树的右子树移到左子树后得到的二叉树的前序遍历数组与后序遍历数组与原二叉树相同,所以只需要考虑第一种情况。因为二叉树的值互不相同,可以在 postorder 中找到 postorder[k]=preorder[1],那么左子树的节点数目为 k+1。基于此,可以对 preorder 和 postorder进行分治处理,即将 preorder 划分为根节点、左子树节点和右子树节点三个部分,postorder也划分为左子树节点、右子树节点和根节点三个部分。那么问题划分为:
- 根据左子树节点的前序遍历与后序遍历数组构造二叉树;
- 根据右子树节点的前序遍历与后序遍历数组构造二叉树。
同时当节点数目为 1 时,对应构造的二叉树只有一个节点。可以递归地对问题进行求解,就可得到构造的二叉树。
时间复杂度:O(n)
空间复杂度:O(n)
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {Map<Integer,Integer> map=new HashMap<>();//为了减少遍历后序序列,使用哈希表存储for(int i=0;i<postorder.length;i++){map.put(postorder[i],i);}return createTree(preorder,postorder,0,preorder.length-1,0,postorder.length-1,map);}
public TreeNode createTree(int[] preorder,int[] postorder,int preL,int preR,int postL,int postR,Map<Integer,Integer> map){if(preL>preR||postL>postR)return null;if(preL==preR)return new TreeNode(preorder[preL]);int val=preorder[preL];//下一个在前序中的根节点在后序中的位置int index=map.get(preorder[preL+1]);//左子树的节点数int left=index-postL+1;TreeNode root=new TreeNode(val);root.left=createTree(preorder,postorder,preL+1,preL+left,postL,index,map);root.right=createTree(preorder,postorder,preL+left+1,preR,index+1,postR-1,map);return root;
}
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~