题目一:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回它的头节点。节点定义如下:
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int val) { this.val = val; } }
解法:根据前序遍历和中序遍历的特性,先找到前序遍历的第一个节点即根结点,此节点在中序序列中的位置左边为左子树节点,右边为右子树节点,于是找到在前序序列中的划分,递归此过程得到最终解。
// just for test
public class Test {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public static TreeNode rebuildBinaryTree(int[] pre, int[] mid) {
if ((pre.length != mid.length) || pre.length == 0)
return null;
TreeNode root = new TreeNode(pre[0]);
int leftCounts = 0;
for (int i=0; i<mid.length; i++) {
if (root.val == mid[i])
break;
leftCounts++;
}
int[] leftPre = new int[leftCounts];
int[] leftMid = new int[leftCounts];
int[] rightPre = new int[pre.length - leftCounts - 1];
int[] rightMid = new int[pre.length - leftCounts - 1];
for (int i=1; i<pre.length; i++) {
if (i <= leftCounts)
leftPre[i-1] = pre[i];
else
rightPre[i-leftCounts-1] = pre[i];
}
for (int i=0; i<mid.length; i++) {
if (i == leftCounts)
continue;
else if (i < leftCounts)
leftMid[i] = mid[i];
else
rightMid[i-leftCounts-1] = mid[i];
}
root.left = rebuildBinaryTree(leftPre, leftMid);
root.right = rebuildBinaryTree(rightPre, rightMid);
return root;
}
public static void main(String[] args) {
TreeNode root = rebuildBinaryTree(new int[]{1,2,4,7,3,5,6,8}, new int[]{4,7,2,1,5,3,8,6});
System.out.println(root.val);
}
}
题目二:给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的结点除了有两个分别指向左、右子结点的指针,还有一个指向父节点的指针。
解法:中序遍历的下一个节点,要么是当前节点右子树最左下的节点,要么是它遍历祖先节点第一个向右走的节点。
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode parent;
TreeNode(int val) {
this.val = val;
}
}
public TreeNode findNextTreeNode(TreeNode current) {
if (current == null)
return null;
if (current.right != null)
return findLeftDownTreeNode(current.right);
return findRightUpTreeNode(current)
}
public TreeNode findLeftDownTreeNode(TreeNode current) {
if (current.left != null)
return findLeftDownTreeNode(current.left);
return current;
}
public TreeNode findRightUpTreeNode(TreeNode current) {
if (current.parent == null)
return null;
if (current.parent.left == current)
return currenet.parent;
return findRightUpTreeNode(current.parent);
}