1、 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
public TreeNode buildTree(int[] preorder, int[] inorder) {
if ( preorder.length== 0)
return null;
int rootval = preorder[0], rootIndex = 0;
for(int i=0;i<preorder.length;i++){
//找中序序列中的根节点的索引
if(inorder[i]==rootval ){
rootIndex=i;
break;
}
}
TreeNode s=new TreeNode(rootval);
//Arrays.copyOfRange(T[ ] original,int from,int to) 将一个原始的数组original,从下标from开始复制,复制到上标to,生成一个新的数组
s.left=buildTree(Arrays.copyOfRange(preorder,1,1+rootIndex),Arrays.copyOfRange(inorder,0,rootIndex)); s.right=buildTree(Arrays.copyOfRange(preorder,1+rootIndex,preorder.length),Arrays.copyOfRange(inorder,rootIndex+1,preorder.length));
return s;
}
思路:这个效率高,但只能使用与前中序列没有重复的元素
root root+1 i-left+1+root
前序数组 根 | 左子树 | 右子树
left i-1 i i+1 right
中序数组 左子树 | 根 | 右子树
i - left + root + 1含义为 根节点索引 + 左子树长度 + 1
int[] preorder;
HashMap<Integer, Integer> dic = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
//将中序的值放入hashmap
for(int i = 0; i < inorder.length; i++)
dic.put(inorder[i], i);
return recur(0, 0, inorder.length - 1);
}
//构建树
TreeNode recur(int root, int left, int right) {
if(left > right) return null; // 递归终止
TreeNode node = new TreeNode(preorder[root]); // 建立根节点
int i = dic.get(preorder[root]); // 划分根节点、左子树、右子树
node.left = recur(root + 1, left, i - 1); // 开启左子树递归
node.right = recur(root + i - left + 1, i + 1, right); // 开启右子树递归
return node; // 回溯返回根节点
}
2、平衡二叉树
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
给定二叉树 [3,9,20,null,null,15,7],返回true
思路: 后序遍历 + 剪枝 (从底至顶)
对二叉树做后序遍历,从底至顶返回子树深度,判定某子树不是平衡树则 “剪枝” ,直接向上返回。
//为-1说明不是平衡二叉树
public boolean isBalanced(TreeNode root) {
return cont(root) != -1;
}
private int cont(TreeNode root){
if(root==null) return 0;
int left=cont(root.left);
if(left == -1) return -1;
int right=cont(root.right);
if(right == -1) return -1;
return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1;
}
思路:先序遍历 + 判断深度 (从顶至底)会产生大量重复计算,时间复杂度较高
通过比较某子树的左右子树的深度差 <= 1 是否成立,来判断某子树是否是二叉平衡树。若所有子树都平衡,则此树平衡。
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
private int depth(TreeNode root) {
if (root == null) return 0;
return Math.max(depth(root.left), depth(root.right)) + 1;
}
3、 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/
2 2
/ \ /
3 4 4 3
思路:找两个节点往下判断是否是对称的
public boolean isSymmetric(TreeNode root) {
return root == null ? true : recur(root.left, root.right);
}
//对称 左节点的左节点 && 右节点的右节点 左节点的右节点 && 右节点的左节点
boolean recur(TreeNode L, TreeNode R) {
if(L == null && R == null) return true;
if(L == null || R == null || L.val != R.val) return false;
return recur(L.left, R.right) && recur(L.right, R.left);
}
4、二叉树的镜像
请完成一个函数,输入一个二叉树,该函数输出它的镜像
**思路1:**使用递归的思想 根节点的左右节点兑换
public TreeNode mirrorTree(TreeNode root) {
if(root==null){
return null;
}
TreeNode tmp=root.left;
root.left=mirrorTree(root.right);
root.right=mirrorTree(tmp);
return root;
}
**思路:**使用额外的空间-栈
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack =