主要涉及:
二叉树的遍历、路径和、翻转、镜像、子树、和链表转换
1。二叉树的先序遍历
List<Integer> res=new ArrayList<Integer>();
public static List<Integer> preOrder(TreeNode root){
if(root==null) return res;
res.add(root.val);
preOrder(root.left);
preOrder(root.right);
return res;
}
2。二叉树的中序遍历
List<Integer> res=new ArrayList<Integer>();
public static List<Integer> inOrder(TreeNode root){
if(root==null) return res;
inOrder(root.left);
res.add(root.val);
inOrder(root.right);
return res;
}
3。二叉树的后序遍历
List<Integer> res=new ArrayList<Integer>();
public static List<Integer> afterOrder(TreeNode root){
if(root==null) return res;
afterOrder(root.left);
afterOrder(root.right);
res.add(root.val);
return res;
}
4、层次遍历,使用一个队列作为存储
public static List<Integer> levelOrder(TreeNode root){
List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
Queue<TreeNode> q=new LinkedList<TreeNode>();
q.add(root);
while(!q.isEmpty()){
int n=q.size();
List<Integer> tmp=new ArrayList<>();
for(int i=0;i<n;i++){
TreeNode node=q.poll();
tmp.add(node.val);
if(node.left!=null) q.add(node.left);
if(node.right!=null) q.add(node.right);
}
res.add(tmp);//res.add(index,value);可以放到指定的位置
}
return res;
}
5、zigzag就是层次遍历的时候偶数层是从左向右,奇数层从右向左。使用两个栈为实现,记录当前层和下一层
public static List<List<Integer>> zigLevel(TreeNode root){
List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
Stack<TreeNode> currlevel=new Stack<TreeNode>();
Stack<TreeNode> nextlevel=new Stack<TreeNode>();
currlevel.add(root);
boolean flag=true;
while(!currlevel.isEmpty()){
List<Integer> currResult=new ArrayList<Integer>();
while(!currlevel.isEmpty()){
TreeNode node=currlevel.pop();
currResult.add(node.val);
if(flag){
if(node.right!=null){
nextlevel.push(node.right);
}
if(node.left!=null){
nextlevel.push(node.left);
}
}
else{
if(node.left!=null){
nextlevel.push(node.left);
}
if(node.right!=null){
nextlevel.push(node.right);
}
}
}
res.add(currResult);
Stack<TreeNode> tmp=currlevel;
currlevel=nextlevel;
nextlevel=tmp;
flag=!flag;
}
return res;
}
6,二叉树的镜像翻转
public static TreeNode mirrorReverse(TreeNode root){
if(root==null) return root;
TreeNode tmp=mirrorReverse(root.left);
root.left=mirrorReverse(root.right);
root.right=tmp;
return root;
}
7,判断二叉树是不是镜像二叉树,前序遍历和镜像前序遍历
public static boolean mirrorTree(TreeNode root){
if(root==null) return false;
return helper(root,root);
}
public static boolean helper(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null) return true;
if(root1==null||root2==null) return false;
if(root1.val!=root2.val) return false;
return helper(root1.left,root2.right)&&helper(root1.right,root2.left);
}
8,判断两个二叉树是不是相同
public static boolean sameTree(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null) return true;
if(root1==null||root2==null) return false;
if(root1.val!=root2.val) return false;
return sameTree(root1.left,root2.left)&&sameTree(root1.right,root2.right);
}
9,判断一个树是不是两一个树的子结构
public static boolean isSubtree(TreeNode root1,TreeNode root2){
if(root1==null&&root2==null) return true;
if(root1==null) return false;
boolean flag=false;
if(root1!=null&&root2!=null){
if(root1.val==root2.val){
flag=match(root1,root2);
}
if(!flag){
flag=isSubtree(root1.left,root2);
}
if(!flag){
flag=isSubtree(root1.right,root2);
}
}
return flag;
}
public static boolean match(TreeNode root1,TreeNode root2){
if(root1==null) return false;
if(root2==null) return true;
if(root1.val!=root2.val) return false;
return match(root1.left,root2.left)&&match(root1.right,root2.right);
}
10,判断一个序列是不是二叉搜索树的后序遍历,搜索树是左<中<右,后续遍历是左右中,找到左子树和递归判断
public static boolean isPopstOrder(int[] a,int start,int to){
if(a.length<0) return false;
int index=start;
while(index<to-1&&a[index]<a[to]){
index++;
}
int i=index;
while(index<to-1&&a[index]>a[to]){
index++;
}
if(index!=to-1){
return false;
}
return isPopstOrder(a,start,index-1)&&isPopstOrder(a,index,to-1);
}
11,把一个二叉搜索树转换成双向链表
public static TreeNode converse(TreeNode root){
if(root==null) return null;
if(root.left==null&&root.right==null){
return root;
}
TreeNode left=converse(root.left);
TreeNode p=left;
while(p.right!=null&&p!=null){
p=p.right;
}
if(left!=null){
p.right=root;
root.left=p;
}
TreeNode right=converse(root.right);
if(right!=null){
right.left=root;
root.right=right;
}
return left!=null?left:root;
}
12,重建二叉树,根据前序遍历和中序遍历递归构建左右子树,
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
}
public static BinaryTreeNode rebuildTree(int [] prerder,int [] inOrder){
if(prerder==null||inOrder==null||preOrder.length!=inOrder.length) return null;
return (preOrder,0,preOrder.length-1,inOrder,0,inOrder.length-1);
}
public static BinaryTreeNode helper(int [] preOrder,int ps,int pe,int [] inOrder,int is,int ie){
if(ps>pe) return null;
int val=preOrder[ps];
int index=is;
while(index<=ie&&inOrder[index]!=val){
index++;
}
BinaryTreeNode node=new BinaryTreeNode();
node.val=val;
node.left(preOrder,ps+1,ps+index-is,inOrder,is,index-1);
node.right(preOrder,ps+index-is+1,pe,inOrder,index+1,ie);
return node;
}
13,二叉树的最大深度
public static int maxDep(TreeNode root){
if(root==null) return 0;
return Math.max(maxDep(root.left),maxDep(root.right))+1;
}
14,二叉树的最小深度
public static int minDep(TreeNode root){
if(root==null) return 0;
if(root.left==null) return minDep(root.right)+1;
if(root.right==null) return minDep(root.left)+1;
return Math.min(minDep(root.left),minDep(root.right))+1;
}
15,判断二叉树的路径和是否有一条和给定的目标值一样
public static boolean pathSum(TreeNode root,int val){
if(root==null) return false;
if(root.left==null&&root.right==null&&root.val==val){
return true;
}
return pathSum(root.left,val-root.val)||pathSum(root.right,val-root.val);
}
16,找出所有路径和为目标值的路径来
int[] save=new int[1000];
List<List<Integer>> res=new ArrayList<>();
public static List<List<Integer>> pathSum(TreeNode root,int val){
if(root==null) return res;
helper(root,val,0);
return res;
}
public static void helper(TreeNode root,int val,int index){
if(root==null) return;
save[index]=root.val;
if(root.val==val&&root.left==null&&root.right==null){
List<Integer> tmp=new ArrayList<>();
for(int i=0;i<=index;i++){
tmp.add(save[i]);
}
res.add(tmp);
return;
}
helper(root.left,val-root.val,index+1);
helper(root.right,val-root.val,index+1);
}
17,求出二叉树的所有的叶子节点
public static int leafCount(TreeNode root){
if(root==null) return 0;
if(root.left==null&&root.right==null){
return 1;
}
return leafCount(root.left)+leafCount(root.right);
}
18,判断是不是平衡二叉树
public static boolean balanceTree(TreeNode root){
if(root==null) return false;
if(Math.abs(maxDep()-maxDep())>1) return false;
return balanceTree(root.left)&&balanceTree(root.right);
}
public static int maxDep(TreeNode root){
if(root==null) return 0;
return Math.max(maxDep(root.left),maxDep(root.right))+1;
}
19,二叉树的所有路径和,1-2-3的路径和看做是123
public static int sumTree(TreeNode root){
if(root==null) return 0;
return helper(root,0);
}
public static int helper(TreeNode root,int sum){
if(root==null) return 0;
if(root.left==null&&root.right==null){
return sum*10+root.val;
}
return helper(root.left,sum*10+root.val)+helper(root.right,sum*10+root.val);
}
20,树中叶子节点的最低公共祖先,使用链表存储到2个叶子节点的路径,然后去寻找链表的最后一个公共节点,如果是二叉树就简单点
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == p || root == q || root == null) { return root; }
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return (left != null && right != null) ? root : (left != null ? left : right);
}
二叉搜索树会更简单一点
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
int max = Math.max(p.val, q.val);
int min = Math.min(p.val, q.val);
while (!(max >= root.val && min <= root.val))
root = root.val < min ? root.right : root.left;
return root;
}
二叉树的面试题目总结
最新推荐文章于 2024-07-22 22:12:00 发布