LeetCode算法题-Quad Tree Intersection(Java实现)

这是悦乐书的第260次更新,第273篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第127题(顺位题号是558)。四叉树是树数据,其中每个内部节点恰好有四个子节点:topLeft,topRight,bottomLeft和bottomRight。四叉树通常用于通过递归地将二维空间细分为四个象限或区域来划分二维空间。

我们想在我们的四叉树中存储true/false。四叉树用于表示N * N布尔网格。对于每个节点,它将被细分为四个子节点,直到它所代表的区域中的值全部相同。每个节点都有另外两个布尔属性:isLeaf和val。当且仅当节点是叶节点时,isLeaf才为真。叶节点的val属性包含它所代表的区域的值。

例如,下面是两个四叉树A和B:

A:
+-------+-------+   T: true
|       |       |   F: false
|   T   |   T   |
|       |       |
+-------+-------+
|       |       |
|   F   |   F   |
|       |       |
+-------+-------+
topLeft: T
topRight: T
bottomLeft: F
bottomRight: F

B:               
+-------+---+---+
|       | F | F |
|   T   +---+---+
|       | T | T |
+-------+---+---+
|       |       |
|   T   |   F   |
|       |       |
+-------+-------+
topLeft: T
topRight:
     topLeft: F
     topRight: F
     bottomLeft: T
     bottomRight: T
bottomLeft: T
bottomRight: F

您的任务是实现一个将需要两个四叉树并返回表示两棵树的逻辑OR(或并集)的四叉树的函数。

A:                 B:                 C (A or B):
+-------+-------+  +-------+---+---+  +-------+-------+
|       |       |  |       | F | F |  |       |       |
|   T   |   T   |  |   T   +---+---+  |   T   |   T   |
|       |       |  |       | T | T |  |       |       |
+-------+-------+  +-------+---+---+  +-------+-------+
|       |       |  |       |       |  |       |       |
|   F   |   F   |  |   T   |   F   |  |   T   |   F   |
|       |       |  |       |       |  |       |       |
+-------+-------+  +-------+-------+  +-------+-------+

注意:

  • A和B都表示大小为N * N的网格。

  • N保证是2的幂。

  • 如果您想了解有关四叉树的更多信息,可以参考其维基。

  • 逻辑OR运算定义如下:如果A为true,或者如果B为true,或者如果A和B都为true,则“A或B”为true。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 解题

题目描述了一种新的数据结构,四叉树,要求计算出两个四叉树的并集,以一个新的四叉树作为结果返回。

一个四叉树含多个内部节点,每个内部节点拥有四个子节点,每个节点拥有两个属性isLeaf和val,只有四个子节点都是叶子节点时,该节点本身的isLeaf属性才会为true,只有四个子节点的值都相同(都为true或false)时,该节点本身的val属性才会为true或false,与其四个子节点的val值等同。

我们直接使用递归,如果quadTree1活着quadTree2是叶子节点,并且其val属性为true,直接返回quadTree1或quadTree2。如果都不是叶子节点,那么就对其四个子节点作为参数,调用自身,进行二次操作,返回的节点组成新的节点的子节点,接着计算新节点的两个属性isLeaf和val,最后返回该新节点即可。在本题中,我们直接使用quadTree1作为新的节点,当然,你也可以创建一个新的Node对象来承接。

public Node intersect(Node quadTree1, Node quadTree2) {
    if (quadTree1.isLeaf) {
        return quadTree1.val ? quadTree1 : quadTree2;
    }
    if (quadTree2.isLeaf) {
        return quadTree2.val ? quadTree2 : quadTree1;
    }
    quadTree1.topLeft = intersect(quadTree1.topLeft, quadTree2.topLeft);
    quadTree1.topRight = intersect(quadTree1.topRight, quadTree2.topRight);
    quadTree1.bottomLeft = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft);
    quadTree1.bottomRight = intersect(quadTree1.bottomRight, quadTree2.bottomRight);
    if (quadTree1.topLeft.isLeaf && quadTree1.topRight.isLeaf
            && quadTree1.bottomLeft.isLeaf && quadTree1.bottomRight.isLeaf
            && quadTree1.topLeft.val == quadTree1.topRight.val
            && quadTree1.topRight.val == quadTree1.bottomLeft.val
            && quadTree1.bottomLeft.val == quadTree1.bottomRight.val) {
        quadTree1.isLeaf = true;
        quadTree1.val = quadTree1.topLeft.val;
    }
    return quadTree1;
}

03 小结

算法专题目前已日更超过三个月,算法题文章127+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

posted @ 2019-02-26 08:23  程序员小川  阅读(751)  评论(0编辑  收藏  举报