850. 矩形面积 II

我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标, (xi1, yi1) 是该矩形 左下角 的坐标, (xi2, yi2) 是该矩形 右上角 的坐标。
计算平面中所有 rectangles 所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次
返回 总面积 。因为答案可能太大,返回 109 + 7 的

示例 1:
image.png
输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]] 输出:6 解释:如图所示,三个矩形覆盖了总面积为6的区域。 从(1,1)到(2,2),绿色矩形和红色矩形重叠。 从(1,0)到(2,3),三个矩形都重叠。
示例 2:
输入:rectangles = [[0,0,1000000000,1000000000]] 输出:49 解释:答案是 1018 对 (109 + 7) 取模的结果, 即 49 。

提示:

  • 1 <= rectangles.length <= 200
  • rectanges[i].length = 4
  • 0 <= xi1, yi1, xi2, yi2 <= 109
  • 矩形叠加覆盖后的总面积不会超越 2^63 - 1 ,这意味着可以用一个 64 位有符号整数来保存面积结果。

思路:按x轴分段考虑
时间复杂度:O(n2logn)

  1. class Solution {
  2. public int rectangleArea(int[][] rectangles) {
  3. int n = rectangles.length;
  4. int[] a = new int[2 * n];
  5. for (int i = 0; i < n; i ++) {
  6. a[i] = rectangles[i][0];
  7. a[i + n] = rectangles[i][2];
  8. }
  9. Arrays.sort(a);
  10. long res = 0;
  11. for (int i = 1; i < 2 * n; i++) {
  12. res += calc(rectangles, a[i - 1], a[i]);
  13. }
  14. return (int)(res % 1000000007);
  15. }
  16. long calc(int[][] r, int x, int y) {
  17. List<int[]> t = new ArrayList<>();
  18. for (int[] p : r) {
  19. if (p[0] <= x && p[2] >= y) {
  20. t.add(new int[]{p[1], p[3]});
  21. }
  22. }
  23. Collections.sort(t, (o1, o2) -> (o1[0] - o2[0]));
  24. long s = 0;
  25. int ll = -1, rr = -1;
  26. for (int[] p : t) {
  27. if (p[0] <= rr) {
  28. rr = Math.max(rr, p[1]);
  29. } else {
  30. s += 1L * (rr - ll) * (y - x);
  31. ll = p[0];
  32. rr = p[1];
  33. }
  34. }
  35. s += 1L * (rr - ll) * (y - x);
  36. return s;
  37. }
  38. }