剑指 Offer 07. 重建二叉树
题目
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
限制:
0 <= 节点个数 <= 5000
题解
先根据两个序列寻找根节点,划分出各自的子树序列,递归构建二叉树。
Code
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null || inorder == null){
return null;
}
TreeNode tn = build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
return tn;
}
public static TreeNode build(int[] preorder, int l1, int r1, int[] inorder, int l2, int r2){
if(l1 > r1 && l2 > r2){
return null;
}
int index = 0;
for(int i = l2; i <= r2 ; i++){
if(inorder[i] == preorder[l1]){
index = i;
break;
}
}
int count = index - l2;
TreeNode tn = new TreeNode(preorder[l1]);
tn.left = build(preorder, l1 + 1, l1 + count, inorder, l2, l2 + count - 1);
tn.right = build(preorder, l1 + count + 1, r1, inorder, l2 + count + 1, r2);
return tn;
}
}
扩展
面试题8:
题目:
给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左、右子节点的指针、还有一个指向父节点的指针。
题解:
当该节点右子树不为空时,下一个节点为该节点右子树的最左子节点;
当该节点右子树为空时:若该节点为其父节点的左子树根节点,则下一个节点就是父节点;若该节点为其父节点的右子树根节点,则继续向上遍历,找到第一个是其父节点的左子树根节点的节点,其父节点就是下一个节点。
Code:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode parent;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode findNextNode(TreeNode node) {
if(node == null){
return null;
}
TreeNode p = null;
if(node.right != null){
p = node.right;
while(p.left != null){
p = p.left;
}
} else if(node.parent != null){
p = node.parent;
TreeNode q = node;
while(p != null && p.right == q){
q = p;
p = p.parent;
}
}
return p;
}
}