哔哩哔哩9.1笔试题解+注释

1. 小红的链表结点合并

    public static class ListNode {
        int val;
        ListNode next = null;

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


    public static ListNode mergeNode(ListNode head) {
        if (head == null) {
            return null;
        }

        ListNode dummy = new ListNode(0), cur = dummy;

        while (head != null && head.next != null) {
            int a = head.val;
            head = head.next;
            int b = head.val;
            cur.next = new ListNode(a * b);
            cur = cur.next;
            head = head.next;
        }

        return dummy.next;
    }

2.小红的最大层权值

前置知识:怎么判断一棵树是否是平衡二叉树
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        return process(root) >= 0;
    }

    public int process(TreeNode x) {
        if (x == null) {
            return 0;
        }
        int left = process(x.left);
        int right = process(x.right);

        if (left >= 0 && right >= 0 && Math.abs(left - right) <= 1) {
            return Math.max(left, right) + 1;
        } else {
            return -1;
        }
    }
public static class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

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

    public static int maxValue(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        // 深度
        int deep = 0;
        // income[i]代表第i层通过交换能获得的最大收益,默认为0
        int maxDeep = maxDeep(root);
        int[] income = new int[maxDeep];
        int[] sums = new int[maxDeep];
        // bfs
        while (!queue.isEmpty()) {
            int size = queue.size();
            // 这一层的权值和
            int curSum = 0;
            for (int i = 0; i < size; i++) {
                // 遍历这一层的所有结点
                TreeNode x = queue.poll();
                // 统计这一层的权值和
                curSum += x.val;
                // 当前到达第n层
                // case 1: x结点 与 n + 1 层自己的左右结点交换,能给 第 n 层的带来最大收益。
                // case 2: x结点 与 n + 1 层自己的左右结点交换,能给 第 n + 1 层的带来最大收益。

                // case 1
                // 当前结点和左孩子交换获得的收益(左孩子.val - x.val)
                int leftInCome = 0;
                if (x.left != null) {
                    leftInCome = x.left.val - x.val;
                    queue.add(x.left);
                }
                // 当前结点和右孩子交换获得的收益
                int rightInCome = 0;
                if (x.right != null) {
                    rightInCome = x.right.val - x.val;
                    queue.add(x.right);
                }
                // 存入income数组中,代表第deep层通过交换能获得的最大收益
                int curMax = Math.max(0, Math.max(leftInCome, rightInCome));
                income[deep] = Math.max(income[deep], curMax);


                // case 2
                // x结点换到自己的左孩子交换获取的收益(x.val - 左孩子.val)
                if (deep + 1 != maxDeep) {
                    leftInCome = -leftInCome;
                    rightInCome = -rightInCome;
                    int curMax2 = Math.max(0, Math.max(leftInCome, rightInCome));
                    income[deep + 1] = Math.max(income[deep + 1], curMax2);
                }
            }

            // 遍历完一层,深度 + 1。同时记录这一层的权值和
            sums[deep++] = curSum;
        }
        
        
        // 遍历sums数组
        int res = 0;
        for (int i = 0; i < sums.length; i++) {
            res = Math.max(res, sums[i] + income[i]);
        }
        return res;
    }

    // 返回二叉树的最大深度
    public static int maxDeep(TreeNode x) {
        if (x == null) {
            return 0;
        }
        return Math.max(maxDeep(x.left), maxDeep(x.right)) + 1;
    }

3. 平衡二叉树

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

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

    static PriorityQueue<TreeNode> queue = new PriorityQueue<>((t1, t2) -> {
        // 获取t1、t2的结点个数
        int nodes1 = treeNodes(t1);
        int nodes2 = treeNodes(t2);
        if (nodes1 == nodes2) {
            // 如果结点个数相同,按照子树的头结点从小到大排序
            return t1.val - t2.val;
        } else {
            // 如果结点个数不同,按照结点数量从小到大排序
            return nodes1 - nodes2;
        }

    });

    public static TreeNode[] balanceSubTree(TreeNode root) {
        if (root == null) {
            // base case
            return new TreeNode[]{};
        }
        // 后序遍历
        process(root);
        // 最后加入剩下的头结点
        queue.add(root);

        TreeNode[] ret = new TreeNode[queue.size()];
        int index = 0;
        while (!queue.isEmpty()) {
            ret[index++] = queue.poll();
        }
        return ret;
    }

    private static int process(TreeNode x) {
        if (x == null) {
            return 0;
        }

        int left = process(x.left);
        int right = process(x.right);
        if (left >= 0 && right >= 0 && Math.abs(left - right) <= 1) {
            // 如果左树是平衡二叉树并且右树是平衡二叉树,并且左树右树高度差不超过1,那么这棵树是平衡二叉树
            // 返回最大高度
            return Math.max(left, right) + 1;
        } else {
            // 不是平衡二叉树,需要拆分。
            if (left > right) {
                // 如果左树高度大于右树高度
                // 左树无论如何都要加入的
                queue.add(x.left);
                // 置空x的左树
                x.left = null;
                // 这里就分为两种情况,第一种情况右树高度小于等于1。第二种情况右树高度大于1
                // case1:右树高度小于等于1,那么这棵树高度为0或者为1,都可以和当前头结点构成平衡二叉树。不用单独将右树加入返回结果
                // case2: 右树高度大于1,也就是大于等于2,因为左树已经置空了,当前头结点加上这个高度大于等于2的子树,构成不了平衡二叉树。所以直接将右树加入
                if (right <= 1) {
                    // case 1 右树不需要单独处理,返回当前头结点 + 右树高度
                    return right + 1;
                } else {
                    // case 2 右树需要单独处理,返回头结点的高度,也就是1
                    queue.add(x.right);
                    x.right = null;
                    return 1;
                }
            } else {
                // 左树高度小于右树高度,情况分析和上面一样
                queue.add(x.right);
                // 置空x的右树
                x.right = null;
                if (left <= 1) {
                    // case 1
                    return left + 1;
                } else {
                    // case 2
                    queue.add(x.left);
                    x.left = null;
                    return 1;
                }
            }
        }
    }

    // 返回一棵树的结点个数
    public static int treeNodes(TreeNode x) {
        if (x == null) {
            return 0;
        }
        return treeNodes(x.left) + treeNodes(x.right) + 1;
    }




#哔哩哔哩#
全部评论
感谢大佬
点赞 回复 分享
发布于 2022-09-03 14:02 河北

相关推荐

昨天 12:43
已编辑
门头沟学院 C++
点赞 评论 收藏
分享
10-18 13:01
已编辑
西安理工大学 C++
小米内推大使:建议技能还是放上面吧,hr和技术面试官第一眼想看的应该是技能点和他们岗位是否匹配
点赞 评论 收藏
分享
4 14 评论
分享
牛客网
牛客企业服务