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);}
}