二叉树基础题(四):对称二叉树的判断&之字形分层遍历二叉树


(尊重劳动成果,转载请注明出处:https://yangwenqiang.blog.csdn.net/article/details/105923803
冷血之心的博客)

这段时间完成了职业生涯第一次跳槽,对算法题目有了一个更深的认识和理解,这里将二叉树常见的面试题目以及解法补充完善。

二叉树基础题(一):先序遍历&中序遍历&后序遍历

二叉树基础题(二):分层遍历&二叉树深度&是否相同的树

二叉树基础题(三):完全二叉树的判断&平衡二叉树的判断

二叉树基础题(四):对称二叉树的判断&之字形分层遍历二叉树

二叉树基础题(五):二叉树的下一个节点&最低公共祖先节点

二叉树基础题(六):树的子结构&二叉搜索树的判断&镜像二叉树


在本篇博客中,我们一起看两个常见面试题目:

  • 判断二叉树是否是对称二叉树
  • 按照之字形分层遍历二叉树

题目一:判断二叉树是否是对称二叉树

我们先来看一个比较笨的方法吧,既然判断是否是对称二叉树,那么只要其本身和其镜像一样,即是一个对称二叉树,所以,我们可以将该二叉树和其镜像就行一个比较即可。

// 方法一:笨方法
    public boolean isSymmetrical(TreeNode pRoot) {
        // 先求出镜像二叉树
        TreeNode node = getMirror(pRoot);
        return isSymmetrical(pRoot, node);
    }
    // 判断两个树是否相等
    private boolean isSymmetrical(TreeNode pRoot, TreeNode node) {
        if (pRoot == null && node == null) {
            return true;
        }
        if (pRoot == null || node == null) {
            return false;
        }
        if (pRoot.val == node.val) {
            return isSymmetrical(pRoot.left, node.left) && isSymmetrical(pRoot.right, node.right);
        }
        return false;
    }

    // 获取镜像二叉树
    private  TreeNode getMirror(TreeNode pRoot) {
        if (pRoot == null) {
            return null;
        }
        TreeNode root = new TreeNode(pRoot.val);
        root.right = getMirror(pRoot.left);
        root.left = getMirror(pRoot.right);
        return root;
    }

这里需要说明的一点是,在二叉树的算法题目中,我们经常需要就行方法的重载,也就是重新定义一个方法,传入更多的参数(信息),这样可以就行有效的递归调用!!!上边就是一个案例。

当然了,我们也可以直接判断当前的二叉树是否是对称二叉树:

可以迭代使用队列来实现,也可以递归比较得出结果:

 // 迭代解法,利用成对进出的特性
    public boolean isSymmetric(TreeNode root) {
        if(root==null)
            return true;
        Queue<TreeNode> queue = new LinkedList<>();
        // 成对进队
        queue.add(root.left);
        queue.add(root.right);
        while(!queue.isEmpty()){
            // 成对取出
            TreeNode leftNode = queue.remove();
            TreeNode rightNode = queue.remove();
            if(leftNode==null&&rightNode==null)
                continue;
            if(leftNode==null||rightNode==null)
                return false;
            if(leftNode.val==rightNode.val){
              // 继续成对进队列
                queue.add(leftNode.left);
                queue.add(rightNode.right);
                queue.add(leftNode.right);
                queue.add(rightNode.left);
            }else{
                return false;
            }
        }
        return true;
    }

    // 方法2:直接判断是否对称
    // 判断是否是对称二叉树,我们可以直接进行对比判断
    public boolean isSymmetric2(TreeNode root) {
        if(root==null)
            return true;
        return isSame(root.left,root.right);
    }

    private boolean isSame(TreeNode p, TreeNode q){
        if(p==null&&q==null)
            return true;

        if(p!=null&&q!=null){
            return q.val==p.val&&isSame(p.left,q.right)&&isSame(p.right,q.left);
        }
        return false;
    }

哦,差点忘记了,这里是二叉树的定义:

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}

题目二:按照之字形分层遍历二叉树

二叉树基础题(四):对称二叉树的判断&之字形分层遍历二叉树_第1张图片

这个题目考察的分层遍历二叉树的一种变种形式,在最普通的层次遍历中,我们使用了队列来作为辅助数据结构遍历二叉树。

这个题目,我们还是使用队列,但是要充分利用双端队列的特性,即使用其addFirst方法!关键点是要确定当前的层数是奇数层还是偶数层,以此来决定是要将节点添加到队列的队尾还是队头!

代码实现如下:

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}

public class Solution {
    public static void main(String[] args) {


        TreeNode root = new TreeNode(1);
        TreeNode r2 = new TreeNode(2);
        TreeNode r3 = new TreeNode(3);
        TreeNode r4 = new TreeNode(4);
        TreeNode r5 = new TreeNode(5);
        TreeNode r6 = new TreeNode(6);
        TreeNode r7 = new TreeNode(7);

        root.left = r2;
        root.right = r3;
        r2.left = r4;
        r2.right = r5;
        r3.right = r6;
        r3.left = r7;

        LinkedList<LinkedList<Integer>> lists = Print(root);
        for (int i = 0; i < lists.size(); i++) {
            System.out.println(lists.get(i));
        }
    }

    static LinkedList<LinkedList<Integer>> listAll = new LinkedList<LinkedList<Integer>>();
    public static LinkedList<LinkedList<Integer> > Print(TreeNode root) {
        if(root==null)
            return listAll;
        LinkedList<Integer> list = new LinkedList<Integer>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();

        int curLevelNode = 1;
        int nextLevelNode = 0;
        int depth=1;
        TreeNode cur = root;
        queue.add(cur);

        while(!queue.isEmpty()){
            TreeNode node = queue.remove();
            curLevelNode--;
            if(depth%2==0){
                // 双端队列的特性
                list.addFirst(node.val);
            }else{
                list.add(node.val);
            }
            if(node.left!=null){
                queue.add(node.left);
                nextLevelNode++;
            }

            if(node.right!=null){
                queue.add(node.right);
                nextLevelNode++;
            }

            if(curLevelNode==0){
                curLevelNode = nextLevelNode;
                nextLevelNode = 0;
                listAll.add(list);
                list = new LinkedList<Integer>();
                depth++;
            }
        }
        return listAll;
    }
}

这里我们借助了https://blog.csdn.net/qq_25827845/article/details/62424798
文中求解二叉树深度时候的一些代码,可以准确判断当前的层数是奇数还是偶数!

因为是第二篇文章中二叉树基础题(二):分层遍历&二叉树深度&是否相同的树
已经有详细的介绍,这里就不展开介绍了。

总结:

之字形遍历二叉树是笔者在头条面试中手撕的算法,代码挺长,但是思路比较清晰,整体上看难度不大。对称二叉树判断主要掌握在递归时候重载方法的使用。

后续我会继续更新二叉树相关基础题目,感兴趣的同学可以持续关注交流~


注意啦,注意啦~

欢迎大家关注我的牛客专栏《Java开发岗面试题全解析》 ,点击图片查看详情。
二叉树基础题(四):对称二叉树的判断&之字形分层遍历二叉树_第2张图片
Java开发岗高频面试题全解析,专栏共计32节,已经全部更新完毕。

专栏分9个模块来对Java岗位面试中的知识点进行解析,包括通用面试技能,Java基础,Java进阶,网络协议,常见框架以及算法,设计模式等。

专栏串点成面的解析每个面试题背后的技术原理,由浅入深,循序渐进,力争让大家掌握面试题目的背后的技术原理,摒弃背题模式的陋习。


如果对你有帮助,记得点赞哈,欢迎大家关注我的博客,关注公众号(文强的技术小屋),学习更多技术知识,一起遨游知识海洋~

你可能感兴趣的:(面试笔试大全—二叉树)