树相关面试题

8 篇文章 0 订阅
8 篇文章 0 订阅

1.层次遍历二叉树
就是用队列嘛,唯一可能有点问题的就是怎么一层一个数组;每次bfs时,记录一下队列中的元素个数,就表示了这一层有几个结点,然后遍历下一层时指定遍历次数达到本层的结点数目即可,如此反复。

ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        Deque<TreeNode> q = new LinkedList<>();
        if(root == null) return res;
        
        q.offerLast(root);
        while(!q.isEmpty()) {
            int size = q.size();
            ArrayList<Integer> list = new ArrayList<>();
            for (int i = 0; i < size; i ++) {
                TreeNode curr = q.poll();
                if(curr == null) return res;
                list.add(curr.val);
                if(curr.left != null) q.offerLast(curr.left);
                if(curr.right != null) q.offerLast(curr.right);
            }
            res.add(list);
        }
        return res;

2.判断是否为对称二叉树
在这里插入图片描述

只需要想到判断条件就迎刃而解了,既:
递归解决:
1.null认为是对称
2.左右结点全为null/全不为null且val相等则认为对称
3.(eg:)第二层的第一个2的右子树等于第二层第二个2的左子树且第二层的第一个2的左子树等于第二层第二个2的右子树则认为对称,这是递归解决最重要的一步。

public boolean sovle(TreeNode l, TreeNode r) {
        if(l == null && r == null) return true;
        if(l == null && r != null || l != null && r == null) return false;
        
        return l.val == r.val && sovle(l.right, r.left) && sovle(l.left, r.right);
    }
    public boolean isSymmetric (TreeNode root) {
        // write code here
        if(root == null) return true;
        return sovle(root.left, root.right);
    }

迭代解决:用层次遍历是可以的,条件为:
1.每层在队列中的数字必须是对称的
2.结点为null,也需要加入队列,因为可能出现队列对称但由于有null而不对称

和上题一样,每层加一个list,对每个结点判断是否为null,如果为null,则加入-1或其他特定值且不加如其子节点(null的子节点),本层遍历完判断一下是否正确,不正确则返回false即可。

public boolean check(List<Integer> list) {
        for(int i = 0, j = list.size() - 1; i < j; i ++, j --) {
            if(list.get(i) != list.get(j)) return false;
        }
        
        return true;
    }

    public boolean isSymmetric (TreeNode root) {
        if(root == null) return true;
        Deque<TreeNode> q = new LinkedList<>();
        q.offer(root);
        
        while(!q.isEmpty()) {
            int size = q.size();
            List<Integer> list = new ArrayList<>();
            for(int i = 0; i < size; i ++) {
                TreeNode t = q.poll();
                if(t == null) list.add(-1);
                else {
                    list.add(t.val);
                    q.offer(t.left);
                    q.offer(t.right);
                }
            }
            if(!check(list)) return false;
        }
        return true;
    }

3.判断是否为平衡二叉树
条件是必须每个结点的左右子树高度差小于等于1

可以写一个计算每个结点高度的方法,遍历树,每个结点都判断一下;
这个显然可看出,每个结点都计算了多次高度,故可以这样:就是后续遍历,如果该点是平衡二叉树则返回其高度,否则返回false/一个表示false标志。

自顶向下:

private int getHigh(TreeNode root) {
        if(root == null) return 0;
        
        int ll = getHigh(root.left);
        int lr = getHigh(root.right);
        
        return Math.max(ll, lr) + 1;
    }
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) return true;
        if(Math.abs(getHigh(root.left) - getHigh(root.right)) > 1) return false;
        
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }

自下而上:(就是边求边解出了答案,求的结果是下一步的答案)

public int getHigh(TreeNode root) {
        if(root == null) return 0;
        int l = getHigh(root.left);
        int r = getHigh(root.right);
        
        if(l == -1 || r == -1 || Math.abs(l - r) > 1) return -1;
        
        return Math.max(l, r) + 1;
    }
    public boolean IsBalanced_Solution(TreeNode root) {
        return getHigh(root) >= 0;
    }

4.求二叉树两节点的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点(p, q)的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

树的问题基本总能用递归解决,因为树天生就满足递归条件;就是深搜,对于任何一个结点,都有三种情况:
1.p, q分别在它的左右子树
2.p, q在它的左侧
3.p, q在它的右侧

我们规定:如果在找的过程中没有搜到p, q就返回null(这样的话如果某一个结点的左子树返回了null,那么说明其左子树没有p, q),如果找到了p, q就返回本结点(这样的话如果某一个结点的左子树返回了非null,那么说明其左子树有p, q),如果当前结点的右子树有、左子树没有则返回右子树返回的内容,左子树同理。这样的话返回的就是最近公共祖先

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return null;
        if(root == p || root == q) return root;
        TreeNode l = lowestCommonAncestor(root.left, p, q);
        TreeNode r = lowestCommonAncestor(root.right, p, q);
        if(l != null && r != null) return root;
        else if(l == null) return r;
        else return l;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值