6043. 统计包含每个点的矩形数目

简介: 笔记

题目


30.png

样例



31.png

输入:rectangles = [[1,1],[2,2],[3,3]], points = [[1,3],[1,1]]

输出:[1,3]

解释:

第一个矩形只包含点 (1, 1) 。

第二个矩形只包含点 (1, 1) 。

第三个矩形包含点 (1, 3) 和 (1, 1) 。

包含点 (1, 3) 的矩形数目为 1 。

包含点 (1, 1) 的矩形数目为 3 。

所以,我们返回 [1, 3] 。


数据


1 <= rectangles.length, points.length <= 5 * 104

rectangles[i].length == points[j].length == 2

1 <= li, xj <= 109

1 <= hi, yj <= 100

所有 rectangles 互不相同 。

所有 points 互不相同 。


暴力 + 二分


思路:


由于高度最大100,所以考虑以此为突破口。(高:y;长,x)

对每个y都存入对应矩阵的x,并排序。

对每个点都枚100次y,然后二分到大于x的位置,加上贡献。

class Solution {
public:
    vector<int> countRectangles(vector<vector<int>>& rectangles, vector<vector<int>>& points) {
        vector<vector<int>> mp(110, vector<int>());
        for (auto &v: rectangles) mp[v[1]].push_back(v[0]);
        for (auto &v: mp) sort(v.begin(), v.end());
        vector<int> res;
        for (int i = 0; i < points.size(); i++) {
            auto &v = points[i];
            int a = v[0], b = v[1];
            int ans = 0;
            for (int j = 0; j < 110; j++) {
                auto &v = mp[j];
                if(!v.size() || j < b) continue;
                int d = lower_bound(v.begin(), v.end(), a) - v.begin();
                ans += v.size() - d;
            }
            res.push_back(ans);
        }
        return res;
    }
};

二维偏序问题:树状数组


思路:


打包矩阵和点(x,y,i),存入vector中。(标记矩阵INF,点i表示第i个点)


排序完后,倒序遍历vector


排序按x,y,i依次排序

遍历到矩阵,就加进tr数组中

遍历到点,此时t r {tr}tr数组中都是>=x &&>=y

ans[i]=sum(n)−sum(y−1)

class Solution {
public:
    static constexpr int N = 110;
    int tr[N + 1] = {0};
    int lowbit(int x) {
        return x & -x;
    }
    void add(int x, int c) {
        for (int i = x; i <= N; i += lowbit(i)) tr[i] += c;
    }
    int sum(int x) {
        int res = 0;
        for (int i = x; i; i -= lowbit(i)) res += tr[i];
        return res;
    }
    vector<int> countRectangles(vector<vector<int>>& rectangles, vector<vector<int>>& points) {
        vector<pair<pair<int, int>, int>> res;
        for (auto &v: rectangles) {
            res.push_back({{v[0], v[1]}, 0x3f3f3f3f});
        }
        for (int i = 0; i < points.size(); i++) {
            auto &v = points[i];
            res.push_back({{v[0], v[1]}, i});
        }
        sort(res.begin(), res.end());
        vector<int> ans(points.size());
        for (int i = res.size() - 1; i >= 0; i--) {
            auto &v = res[i];
            if(v.second == 0x3f3f3f3f) {
                add(v.first.second, 1);
            } else {
                ans[v.second] = sum(N) - sum(v.first.second - 1);
            }
        }
        return ans;
    }
};

Python


排序 + 双指针

参考灵茶山艾府


思路:


对矩阵和点都进行y {y}y降序排列。

每次插完x {x}x坐标后,对 x s {xs}xs进行排序,二分出> = x {>=x}>=x的矩阵个数。

由于我们是按纵坐标从大到小遍历的,因此这些矩形的纵坐标均不小于y {y}y。

class Solution:
    def countRectangles(self, rectangles: List[List[int]], points: List[List[int]]) -> List[int]:
        rectangles.sort(key=lambda r: -r[1])
        n = len(points)
        ans = [0] * n
        i, xs = 0, []
        for (x, y), id in sorted(zip(points, range(n)), key=lambda x: -x[0][1]):
            start = i
            while i < len(rectangles) and y <= rectangles[i][1]:
                xs.append(rectangles[i][0])
                i += 1
            if start < i:
                xs.sort()  # 只有在 xs 插入了新元素时才排序
            ans[id] = i - bisect_left(xs, x)
        return ans

名次树:(SortedList)

如果x<=1e9 && y<=1e9

from sortedcontainers import SortedList
class Solution:
    def countRectangles(self, rectangles: List[List[int]], points: List[List[int]]) -> List[int]:
        rectangles.sort(key=lambda r: -r[1])
        n = len(points)
        ans = [0] * n
        i, xs = 0, SortedList()
        for (x, y), id in sorted(zip(points, range(n)), key=lambda x: -x[0][1]):
            while i < len(rectangles) and y <= rectangles[i][1]:
                xs.add(rectangles[i][0])
                i += 1
            ans[id] = i - xs.bisect_left(x)
        return ans
相关文章
|
数据可视化
R绘图 | 包含/比例关系环图
R绘图 | 包含/比例关系环图
156 0
|
算法 测试技术 C#
C++前缀和算法应用:矩形区域不超过 K 的最大数值和
C++前缀和算法应用:矩形区域不超过 K 的最大数值和
|
5月前
|
计算机视觉
用calcHist()函数查找直方图
【6月更文挑战第7天】用calcHist()函数查找直方图。
67 2
|
6月前
|
数据挖掘 计算机视觉 Python
Python实现对规整的二维列表中每个子列表对应的值求和
Python实现对规整的二维列表中每个子列表对应的值求和
61 0
|
6月前
|
Serverless
统计问题|绘制任意分布的 QQ 图
统计问题|绘制任意分布的 QQ 图
137 1
|
6月前
leetcode-363:矩形区域不超过 K 的最大数值和
leetcode-363:矩形区域不超过 K 的最大数值和
40 0
|
C语言 C++
1684. 统计一致字符串的数目
给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 。 请你返回 words 数组中 一致字符串 的数目。
97 0
【C++之标准输入输出流】 判断是否符合条件并计算三角形的面积
【C++之标准输入输出流】 判断是否符合条件并计算三角形的面积
|
数据建模 定位技术
7 种 基本比例尺地形图的分幅和编号的数量关系
7 种 基本比例尺地形图的分幅和编号的数量关系
998 0
7 种 基本比例尺地形图的分幅和编号的数量关系