427. 建立四叉树

https://leetcode.cn/problems/construct-quad-tree/description/?envType=study-plan-v2&envId=top-interview-150

思路:这题乍一看很复杂但是只要读懂题找到规律就会发现其实很简单
四叉树的构造规律:
1. 如果一个区域的值全相等,那么这个区域就是叶子节点,val = grid[x][y]==1, isLeaf = true。
2. 如果一个区域的值不全相等,那么这个区域就不是叶子节点,val = 随意(true、false都行), isLeaf = false。
3. 如果一个区域的值不全相等,那么这个新生成的节点不是叶节点所以有四个子节点,每个子节点对应一个子区域;反之叶节点不应该有子节点。

所以我们就可以对grid分治了,每次将它分成四个区域,如果某一区域不能再分了,我们就返回该区域对应节点(一定是leaf),递归结束后我们再按规律合并这四个区域。

class Solution {
    class Node {
        public boolean val;
        public boolean isLeaf;
        public Node topLeft;
        public Node topRight;
        public Node bottomLeft;
        public Node bottomRight;


        public Node() {
            this.val = false;
            this.isLeaf = false;
            this.topLeft = null;
            this.topRight = null;
            this.bottomLeft = null;
            this.bottomRight = null;
        }

        public Node(boolean val, boolean isLeaf) {
            this.val = val;
            this.isLeaf = isLeaf;
            this.topLeft = null;
            this.topRight = null;
            this.bottomLeft = null;
            this.bottomRight = null;
        }

        public Node(boolean val, boolean isLeaf, Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) {
            this.val = val;
            this.isLeaf = isLeaf;
            this.topLeft = topLeft;
            this.topRight = topRight;
            this.bottomLeft = bottomLeft;
            this.bottomRight = bottomRight;
        }
    }
    public Node construct(int[][] grid) {
        Node root = divide(grid, 0, 0, grid.length - 1, grid[0].length - 1);
        return root;
    }

    public Node divide(int[][] grid, int x1, int y1, int x2, int y2) {
        if( x1 == x2 && y1 == y2) {
            return new Node(grid[x1][y1] == 1, true);
        }
        // 把这个区域分成四部分
        int topLeft_x1 = x1, topLeft_y1 = y1, topLeft_x2 = (x1 + x2) / 2, topLeft_y2 = (y1 + y2) / 2;
        int topRight_x1 = x1, topRight_y1 = topLeft_y2 + 1, topRight_x2 = topLeft_x2, topRight_y2 = y2;
        int bottomLeft_x1 = topLeft_x2 + 1, bottomLeft_y1 = y1, bottomLeft_x2 = x2, bottomLeft_y2 = topLeft_y2;
        int bottomRight_x1 = bottomLeft_x1, bottomRight_y1 = topLeft_y2 + 1, bottomRight_x2 = x2, bottomRight_y2 = y2;
        Node topLeftNode = divide(grid, topLeft_x1, topLeft_y1, topLeft_x2, topLeft_y2);
        Node topRightNode = divide(grid, topRight_x1, topRight_y1, topRight_x2, topRight_y2);
        Node bottomLeftNode = divide(grid, bottomLeft_x1, bottomLeft_y1, bottomLeft_x2, bottomLeft_y2);
        Node bottomRightNode = divide(grid, bottomRight_x1, bottomRight_y1, bottomRight_x2, bottomRight_y2);
        return merge(topLeftNode, topRightNode, bottomLeftNode, bottomRightNode);
    }

    public Node merge(Node topLeft, Node topRight, Node bottomLeft, Node bottomRight) {
        // 如果所有子节点全是叶子节点并且它们的值全相等就说明新被构造出的节点也是叶子节点
        // 注意新构造出的叶子节点没有子节点
        if(topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf
        && topLeft.val == topRight.val && topRight.val == bottomLeft.val && bottomLeft.val == bottomRight.val) {
            return new Node(topLeft.val, true, null, null, null, null);
        } else { // 否则新构造出的节点不是叶子节点,该节点的值随意
            return new Node(topLeft.val, false, topLeft, topRight, bottomLeft, bottomRight);
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[][] grid = {{1,1,1,1,0,0,0,0},{1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1}
                        ,{1,1,1,1,0,0,0,0},{1,1,1,1,0,0,0,0}, {1,1,1,1,0,0,0,0},{1,1,1,1,0,0,0,0}};
        solution.construct(grid);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值