Skip to content

Commit acbba7d

Browse files
committed
add for rectangle
1 parent 2917d15 commit acbba7d

5 files changed

+199
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com..houbb.leetcode.datastruct.sweepline;
2+
3+
public class T223_rectangleArea_V1_overlapArea {
4+
5+
6+
public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
7+
int rect1 = rectangleArea(ax1, ay1, ax2, ay2);
8+
int rect2 = rectangleArea(bx1, by1, bx2, by2);
9+
10+
int overlap = rectangleOverlapArea(new int[]{ax1, ay1, ax2, ay2}, new int[]{bx1, by1, bx2, by2});
11+
12+
return rect1-overlap+rect2;
13+
}
14+
15+
private int rectangleArea(int ax1, int ay1, int ax2, int ay2) {
16+
return (ax2-ax1) * (ay2-ay1);
17+
}
18+
19+
public int rectangleOverlapArea(int[] rec1, int[] rec2) {
20+
// 计算交集矩形的左下角和右上角
21+
int x1 = Math.max(rec1[0], rec2[0]);
22+
int y1 = Math.max(rec1[1], rec2[1]);
23+
int x2 = Math.min(rec1[2], rec2[2]);
24+
int y2 = Math.min(rec1[3], rec2[3]);
25+
26+
// 计算交集的宽度和高度
27+
int width = x2 - x1;
28+
int height = y2 - y1;
29+
30+
// 如果交集的宽度和高度都大于 0,说明有重叠
31+
if (width > 0 && height > 0) {
32+
return width * height;
33+
}
34+
35+
// 没有重叠
36+
return 0;
37+
}
38+
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com..houbb.leetcode.datastruct.sweepline;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.List;
7+
8+
public class T223_rectangleArea_V2_Sweepline {
9+
10+
11+
public static void main(String[] args) {
12+
computeArea(1,2,3,4,5,6,7,8);
13+
14+
}
15+
16+
public static int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
17+
int[][] arr = new int[2][];
18+
arr[0] = new int[]{ax1, ay1, ax2, ay2};
19+
arr[1] = new int[]{bx1, by1, bx2, by2};
20+
Arrays.sort(arr, (o1, o2) -> o1[1] == o2[1] ? o1[3] - o2[3] : o1[1] - o2[1]);
21+
List<Integer> xList = Arrays.asList(ax1, ax2, bx1, bx2);
22+
Collections.sort(xList);
23+
int ans = 0;
24+
for (int i = 1; i < 4; i++) {
25+
int width = xList.get(i) - xList.get(i-1);
26+
for (int[] ints : getLine(xList.get(i-1), xList.get(i), arr)) {
27+
ans += width * (ints[1] - ints[0]);
28+
}
29+
}
30+
return ans;
31+
}
32+
33+
private static List<int[]> getLine(int x1, int x2, int[][] arr) {
34+
List<int[]> list = new ArrayList<>();
35+
for (int[] ints : arr) {
36+
if (x1 >= ints[0] && x2 <= ints[2]) {
37+
if (list.isEmpty()) {
38+
list.add(new int[]{ints[1], ints[3]});
39+
} else {
40+
int[] tmp = list.get(list.size() - 1);
41+
if (tmp[1] < ints[1]) {
42+
list.add(new int[]{ints[1], ints[3]});
43+
} else if (tmp[1] < ints[3]) {
44+
tmp[1] = ints[3];
45+
}
46+
}
47+
}
48+
}
49+
return list;
50+
}
51+
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com..houbb.leetcode.datastruct.sweepline;
2+
3+
public class T836_rectangleOverlap_V1 {
4+
5+
public static void main(String[] args) {
6+
T836_rectangleOverlap_V1 v1 = new T836_rectangleOverlap_V1();
7+
System.out.println(v1.isRectangleOverlap(new int[]{7,8,13,15}, new int[]{10,8,12,20}));
8+
}
9+
10+
public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
11+
// 判断 x 轴和 y 轴投影是否有交集
12+
boolean xOverlap = rec1[2] > rec2[0] && rec1[0] < rec2[2];
13+
boolean yOverlap = rec1[3] > rec2[1] && rec1[1] < rec2[3];
14+
15+
// 两个投影都有交集才算重叠
16+
return xOverlap && yOverlap;
17+
}
18+
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com..houbb.leetcode.datastruct.sweepline;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.TreeSet;
6+
7+
public class T836_rectangleOverlap_V2_Sweepline {
8+
9+
public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
10+
// 如果 rec1 和 rec2 的 x 范围没有交集,直接返回 false
11+
if (rec1[2] <= rec2[0] || rec1[0] >= rec2[2] || rec1[3] <= rec2[1] || rec1[1] >= rec2[3]) {
12+
return false;
13+
}
14+
15+
// 创建事件列表
16+
List<int[]> events = new ArrayList<>();
17+
18+
// rec1 生成的事件
19+
events.add(new int[]{rec1[0], rec1[1], rec1[3], 1}); // 左边界
20+
events.add(new int[]{rec1[2], rec1[1], rec1[3], -1}); // 右边界
21+
22+
// rec2 生成的事件
23+
events.add(new int[]{rec2[0], rec2[1], rec2[3], 1}); // 左边界
24+
events.add(new int[]{rec2[2], rec2[1], rec2[3], -1}); // 右边界
25+
26+
// 按 x 坐标排序,若 x 相同,右边界事件优先
27+
events.sort((a, b) -> a[0] == b[0] ? b[3] - a[3] : a[0] - b[0]);
28+
29+
// 使用一个优先队列来维护活动的 y 区间
30+
TreeSet<int[]> activeIntervals = new TreeSet<>((a, b) -> a[0] == b[0] ? Integer.compare(a[1], b[1]) : Integer.compare(a[0], b[0]));
31+
32+
for (int[] event : events) {
33+
int x = event[0], y1 = event[1], y2 = event[2], type = event[3];
34+
35+
if (type == 1) { // 左边界
36+
// 插入 y 区间
37+
activeIntervals.add(new int[]{y1, y2});
38+
39+
// 检查当前是否有重叠
40+
if (hasOverlap(activeIntervals)) {
41+
return true;
42+
}
43+
} else { // 右边界
44+
// 移除 y 区间
45+
activeIntervals.remove(new int[]{y1, y2});
46+
}
47+
}
48+
49+
return false;
50+
}
51+
52+
// 检查是否有 y 区间重叠
53+
private boolean hasOverlap(TreeSet<int[]> activeIntervals) {
54+
int prevEnd = Integer.MIN_VALUE;
55+
for (int[] interval : activeIntervals) {
56+
if (interval[0] < prevEnd) {
57+
return true; // 有重叠
58+
}
59+
prevEnd = interval[1];
60+
}
61+
return false;
62+
}
63+
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com..houbb.leetcode.datastruct.sweepline;
2+
3+
public class T836_rectangleOverlap_V2_overlapArea {
4+
5+
public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
6+
// 计算交集矩形的左下角和右上角
7+
int x1 = Math.max(rec1[0], rec2[0]);
8+
int y1 = Math.max(rec1[1], rec2[1]);
9+
int x2 = Math.min(rec1[2], rec2[2]);
10+
int y2 = Math.min(rec1[3], rec2[3]);
11+
12+
// 计算交集的宽度和高度
13+
int width = x2 - x1;
14+
int height = y2 - y1;
15+
16+
// 如果交集的宽度和高度都大于 0,说明有重叠
17+
if (width > 0 && height > 0) {
18+
return true;
19+
}
20+
21+
// 没有重叠
22+
return false;
23+
}
24+
25+
}

0 commit comments

Comments
 (0)