Leetcode:558. 四叉树交集

133 篇文章 0 订阅

四叉树是一种树数据,其中每个结点恰好有四个子结点:topLefttopRightbottomLeft 和 bottomRight。四叉树通常被用来划分一个二维空间,递归地将其细分为四个象限或区域。

我们希望在四叉树中存储 True/False 信息。四叉树用来表示 N * N 的布尔网格。对于每个结点, 它将被等分成四个孩子结点直到这个区域内的值都是相同的。每个节点都有另外两个布尔属性:isLeaf 和 isLeaf。当这个节点是一个叶子结点时 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

 

你的任务是实现一个函数,该函数根据两个四叉树返回表示这两个四叉树的逻辑或(或并)的四叉树。

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

 

提示:

  1. A 和 B 都表示大小为 N * N 的网格。
  2. N 将确保是 2 的整次幂。
  3. 如果你想了解更多关于四叉树的知识,你可以参考这个 wiki 页面。
  4. 逻辑或的定义如下:如果 A 为 True ,或者 B 为 True ,或者 A 和 B 都为 True,则 "A 或 B" 为 True。

在真实的面试中遇到过这道题?

解题思路:

递归。主要在于理清其中的逻辑关系。

  1. 当合并的两个结点都是叶子节点时,最容易,逻辑取或即可。
  2. 只有其中一个结点是叶子节点时,如果叶子节点val=false,返回另一个结点。若这个叶子节点val=true,返回叶子节点。
  3. 如果两个结点都不是叶子,那么,递归的合并它们的4个孩子,一定要对应。如果合并以后,4个孩子都是叶子,并且它们的val相等,那么4个孩子合并,逻辑值val与孩子相同,当前的结点设置为叶子。

C++代码
static auto x = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    return 0;
}();
class Solution {
public:
    Node* intersect(Node* quadTree1, Node* quadTree2) {
        Node* root;
        if (quadTree1->isLeaf == true) {
            if (quadTree1->val == true) root = quadTree1;
            else root = quadTree2;
            return root;
        }
        if (quadTree2->isLeaf == true) {
            if (quadTree2->val == true) root = quadTree2;
            else root = quadTree1;
            return root;
        }
        root = quadTree1;
        root->bottomLeft = intersect(quadTree1->bottomLeft, quadTree2->bottomLeft);
        root->bottomRight = intersect(quadTree1->bottomRight, quadTree2->bottomRight);
        root->topLeft = intersect(quadTree1->topLeft, quadTree2->topLeft);
        root->topRight = intersect(quadTree1->topRight, quadTree2->topRight);
        root->val=false;
        if ((root->bottomLeft->isLeaf&&root->bottomRight->isLeaf&&root->topLeft->isLeaf&&root->topRight->isLeaf)
            &&((root->bottomLeft->val && root->bottomRight->val && root->topLeft->val && root->topRight->val)
            || (!root->bottomLeft->val && !root->bottomRight->val && !root->topLeft->val && !root->topRight->val))) {
            root->val = root->bottomLeft->val;
            root->bottomLeft = nullptr;
            root->bottomRight = nullptr;
            root->topLeft = nullptr;
            root->topRight = nullptr;
            root->isLeaf = true;
        }
        return root;
    }
};

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
给定一个整数数组 nums 和一个目标值 target,要求在数组中找出两个数的和等于目标值,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标值。如果等于目标值,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的值,查找哈希表中是否存在这个差值。 如果存在,则说明找到了两个数的和等于目标值,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排序,可以使用双指针的方法来求解。假设数组从小到大排序,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标值,则返回它们的索引。如果和小于目标值,则将左指针右移一位,使得和增大;如果和大于目标值,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标值或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值