二叉树的面试题目总结

来源:互联网 发布:手机上怎么看淘宝等级 编辑:程序博客网 时间:2024/06/07 05:10
主要涉及:二叉树的遍历、路径和、翻转、镜像、子树、和链表转换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;    }
0 0
原创粉丝点击