刷题(剑指offer04)
重建二叉树
题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
样例:
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析1:
前序遍历:
若二叉树为空则结束返回,否则:
(1)访问根结点。
(2)前序遍历左子树。
(3)前序遍历右子树 。
中序遍历:
(1)中序遍历左子树
(2)访问根结点
(3)中序遍历右子树
后续遍历:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
题目要求:根据前序遍历和中序遍历重构出二叉树。
分析2:
二叉树的先序遍历:(递归与非递归)
递归:(根左右)
public static void preOrderRec(Node root){
if(root!=null){
System.out.println(root.value);
preOrderRec(root.left);
preOrderRec(root.right);
}
非递归(用栈实现):
public static void preOrder2(TreeNode root) {
if(root==null)return;
Stack<TreeNode> q =new Stack<TreeNode>();
q.add(root);
while(q.isEmpty()==false) {
TreeNode tn = q.pop();
System.out.print(tn.val +" ");//Visit(root)
if(tn.right!=null)q.add(tn.right);//注意是right元素先进栈
if(tn.left!=null)q.add(tn.left);
}
}
Collections和Arrays的常用方法:
Collections方法:
1、 sort(Collection)方法的使用(含义:对集合进行排序)。用法:Collections.sort(list);
2、 reverse()方法的使用(含义:反转集合中元素的顺序)。用法:Collections.reverse(list);
3、 copy(List m,List n)方法的使用(含义:将集合n中的元素全部复制到m中,并且覆盖相应索引的元素,如果n>m,则报错)
4. shuffle:打乱集合元素。
5. copy:复制数组
6.
Arrays方法:
1、Arrays.asList(T… a)将数组/转成列表,例如:List list= Arrays.asList(“Larry”, “Moe”, “Curly”);
*生成的List不可进行add和remove操作,因为它是一个定长的List,跟数组长度一致.
2、Arrays.sort() 对数组进行排序、
3、Arrays.copyOf() 复制指定数组。可以对数组进行扩容,例如ArrayList扩容:
elementData = Arrays.copyOf(elementData, newCapacity)
其本质是调用的系统的System.arraycopy() 的函数。
4.Arrays.copyOfRange(T[] original, int from, int to)
拷贝数组,指定起始位置和结束位置,如果超过原数组长度,会用null进行填充
5.Arrays.equals(Object[] array1, Object[] array2)判断两个数组是否相等,实际上比较的是两个数组的哈希值
6.Arrays.deepToString(Object[] array) 返回多维数组元素的字符串形式Integer[][] data = {{1, 2, 3}, {1, 2, 3}};
System.out.println(Arrays.deepToString(data)); // [[1, 2, 3], [1, 2, 3]]
7.Arrays.stream(T[] array) 返回数组的流Stream,然后我们就可以使用Stream相关的许多方法了
本题的解决思路如下:
由先序遍历知:先序遍历的首节点肯定是根节点。
由中序遍历知:中序遍历的节点左边都为其左子树的内容,节点所在位置的右边都为其右子树的内容。
且关于遍历和二叉树的相关操作,都常用递归的方式进行书写代码,本题的核心在于找到关键点:中序遍历的节点左边都为其左子树的内容,节点所在位置的右边都为其右子树的内容。
故本题的代码可写为:
import java.util.*;
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length == 0||in.length == 0){
return null;
}
TreeNode node = new TreeNode(pre[0]);
for(int i = 0; i < in.length; i++){
if(pre[0] == in[i]){
node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1,in.length));
}
}
return node;
}
}