LeetCode——105. Construct Binary Tree from Preorder and Inorder Traversal
来源:互联网 发布:东华软件金融部 编辑:程序博客网 时间:2024/05/31 00:39
问题的具体描述:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
这道题大致的意思就是,它会给你一棵二叉树的前序遍历序列和中序遍历序列,然后要你根据这两个序列来重建这棵二叉树。
呃因为这道题想表达出我自己的思路有一点点困难,所以叙述过程会有点啰嗦,如果有不懂的地方,或者是文中有错误的地方,欢迎大家提出来。
它给了我们先序遍历和中序遍历的结果,要求重建一个二叉树。根据先序遍历的特点,它首先会一直往左下角走,而根据中序遍历的特点,它会从最左下角往上走,所以我们先顺着先序遍历序列一直往左下角走,同时用一个哈希表来保存已经在树中的点。当它与中序遍历序列中的点相等时,就说明到达了最左边,接着就顺着中序遍历序列往上(往回)走。如果所经过的点在哈希表中,说明该点已经在树中,继续往上走;如果它与先序遍历序列中的点相等时,说明这个点将会成为上一个点的子节点。然后又切换到沿着先序遍历序列走下去······,反复切换。接下来我就根据代码来分析一下具体流程。
(以下所说的往上走或往下走,实际上就是在相应的序列数组中往后移而已)
首先是沿着先序序列往下走,同时不断把选中的点作为上一个点的左子节点或右子节点插入(具体判断在下面说明);如果遇到与中序序列中相等的值,把这个点作为上一个点的左子节点或右子节点插入(具体判断在下面说明),并切换为中序序列,往上(回)走;如果遇到与先序序列中相等的值,把这个点作为上一个点的左子节点或右子节点插入,并切换为先序序列,往下走,并将这个路径上的点作为上一个点的左子节点或右子节点插入(具体判断在下面说明)······一直反复,直到最后满足树的节点数。
至于左子节点还是右子节点,有一个判断依据:如果上一个点已经是一个相等点了,那么就说明上一个点是没有左子节点的,这个不好说清楚,可以自己画图看看,所以就要将它作为右子节点插入。
虽然代码较长,但是因为是非递归,所以速度还是挺快的。
下面是具体的代码:
public TreeNode buildTree(int[] preorder, int[] inorder) if(inorder.length <= 0) { return null; } //用来保存已经在树上的点 Map<Integer, TreeNode> tempMap = new HashMap<>(); TreeNode cur = null; TreeNode root = cur; //前序遍历序列的索引 int preIndex = 0; //中序遍历序列的索引 int inIndex = 0; int size = 0; //是否存在左子节点 boolean notLeft = false; while(size < inorder.length) { //如果这个两个序列中定位到的点相同 if(preorder[preIndex] == inorder[inIndex]) { TreeNode newNode = new TreeNode(preorder[preIndex]); if(root == null) { root = newNode; } else { //如果上一个点不是相等的点,则直接作为上一个点的左子节点插入 if(cur.left == null && !notLeft) cur.left = newNode; //如果上一个点是相等的点,说明上一个点不可能存在左子节点,就要以右子节点插入 else cur.right = newNode; } cur = newNode; size++; //插入到hash表中,说明这个点已被插入到树中 tempMap.put(newNode.val, newNode); //相等时,两个索引都向后移 inIndex++; preIndex++; //将不存在左子节点设为true notLeft = true; } else { //这是在中序遍历序列中后移时遇到的情况,所以对应的索引要向后移 //如果这个点已经在树中了,将当前点设为这个点 if(tempMap.get(inorder[inIndex]) != null) { cur = tempMap.get(inorder[inIndex]); inIndex++; } //这是在前序遍历序列中后移时遇到的情况,所以对应的索引要向后移 //如果这个点不在树中 else { TreeNode newNode = new TreeNode(preorder[preIndex]); if(root == null) { root = newNode; } else { //如果上一个点不是相等的点,则直接作为上一个点的左子节点插入 if(cur.left == null && !notLeft) cur.left = newNode; //如果上一个点是相等的点,说明上一个点不可能存在左子节点,就要以右子节点插入 else cur.right = newNode; } cur = newNode; size++; //插入到hash表中,说明这个点已被插入到树中 tempMap.put(newNode.val, newNode); preIndex++; } //将不存在左子节点设为false notLeft = false; } } return root; }
不得不说,这是一道好题目,只不过我的思路比较复杂,所以表达起来有点问题,希望大家见谅。在原题的讨论中,高票的答案是用了递归来做,我觉得也是一个很好的办法,大家可以去看一看。
- LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
- [Leetcode] 105. Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode --- 105. Construct Binary Tree from Preorder and Inorder Traversal
- [LeetCode]*105.Construct Binary Tree from Preorder and Inorder Traversal
- [leetcode] 105.Construct Binary Tree from Preorder and Inorder Traversal
- Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
- 105. Construct Binary Tree from Preorder and Inorder Traversal LeetCode
- LeetCode#105. Construct Binary Tree from Preorder and Inorder Traversal
- Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode *** 105. Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
- 【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode-105.Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode - 105. Construct Binary Tree from Preorder and Inorder Traversal
- [Leetcode]105. Construct Binary Tree from Preorder and Inorder Traversal
- [LeetCode] 105. Construct Binary Tree from Preorder and Inorder Traversal
- [leetcode] 105. Construct Binary Tree from Preorder and Inorder Traversal
- [leetcode]105. Construct Binary Tree from Preorder and Inorder Traversal
- iframe有哪些缺点?应该怎么合理使用?
- Mac电脑上配置Java开发环境
- log4js 日志模块
- 达夫设备(Duff`s Device)减少迭代次数
- Angular CLI 使用教程指南参考
- LeetCode——105. Construct Binary Tree from Preorder and Inorder Traversal
- 反转单链表
- 简单线程池实现原理
- Codeforces Round #432 (Div. 2) B. Arpa and an exam about geometry(数学水题)
- 几种常见加密算法解析及使用
- UVALive 4764 Bing it(dp)
- Linux的system()和popen()差异
- HTML表格颜色搭配+柱状图颜色搭配+HTML柱状图实现
- Windows Message Queue