@@ -4,61 +4,38 @@ import (
4
4
"sort"
5
5
)
6
6
7
+ // 思路来自 https://leetcode.com/problems/rectangle-area-ii/discuss/137914/C++Python-Discretization-and-O(NlogN)
8
+
7
9
const mod = 1e9 + 7
8
10
9
11
func rectangleArea (rectangles [][]int ) int {
12
+ // 提取 rectangles 中所有的 x 坐标值,并按照升序排列
10
13
xs := getXs (rectangles )
11
- sort .Ints (xs )
12
14
13
- idxX := make (map [int ]int , 2 * len (xs ))
14
- for k , x := range xs {
15
- idxX [x ] = k
15
+ idxs := make (map [int ]int , 2 * len (xs ))
16
+ for idx , x := range xs {
17
+ idxs [x ] = idx
16
18
}
17
19
18
20
count := make ([]int , len (xs ))
19
21
20
- L := make ([][]int , 0 , 2 * len (rectangles ))
21
-
22
- for _ , r := range rectangles {
23
- x1 , y1 , x2 , y2 := r [0 ], r [1 ], r [2 ], r [3 ]
24
- L = append (L ,
25
- []int {y1 , x1 , x2 , 1 },
26
- []int {y2 , x1 , x2 , - 1 },
27
- )
28
- }
29
-
30
- sort .Slice (L , func (i int , j int ) bool {
31
- eq0 := L [i ][0 ] == L [j ][0 ]
32
- eq1 := L [i ][1 ] == L [j ][1 ]
33
- eq2 := L [i ][2 ] == L [j ][2 ]
34
- if eq0 && eq1 && eq2 {
35
- return L [i ][3 ] < L [j ][3 ]
36
- }
37
- if eq0 && eq1 {
38
- return L [i ][2 ] < L [j ][2 ]
39
- }
40
- if eq0 {
41
- return L [i ][1 ] < L [j ][1 ]
42
- }
43
- return L [i ][0 ] < L [j ][0 ]
44
- })
22
+ labels := getLabels (rectangles )
45
23
46
24
curY , curXSum , area := 0 , 0 , 0
47
25
48
- for _ , l := range L {
26
+ for _ , l := range labels {
49
27
y , x1 , x2 , sig := l [0 ], l [1 ], l [2 ], l [3 ]
50
28
area += (y - curY ) * curXSum
51
29
curY = y
52
- for i := idxX [x1 ]; i < idxX [x2 ]; i ++ {
30
+ for i := idxs [x1 ]; i < idxs [x2 ]; i ++ {
53
31
count [i ] += sig
54
32
}
55
33
curXSum = 0
56
34
for i := 0 ; i + 1 < len (count ); i ++ {
57
- if count [i ] != 0 {
35
+ if count [i ] > 0 {
58
36
curXSum += xs [i + 1 ] - xs [i ]
59
37
}
60
38
}
61
-
62
39
}
63
40
64
41
return area % mod
@@ -68,15 +45,43 @@ func getXs(rects [][]int) []int {
68
45
size := len (rects )
69
46
res := make ([]int , 1 , size * 2 )
70
47
xMap := make (map [int ]bool , size * 2 )
71
-
72
48
for _ , r := range rects {
73
49
xMap [r [0 ]] = true
74
50
xMap [r [2 ]] = true
75
51
}
76
-
77
52
for k := range xMap {
78
53
res = append (res , k )
79
54
}
80
-
55
+ sort . Ints ( res )
81
56
return res
82
57
}
58
+
59
+ func getLabels (rects [][]int ) [][]int {
60
+ labels := make ([][]int , 0 , 2 * len (rects ))
61
+ for _ , r := range rects {
62
+ x1 , y1 , x2 , y2 := r [0 ], r [1 ], r [2 ], r [3 ]
63
+ labels = append (labels ,
64
+ []int {y1 , x1 , x2 , 1 },
65
+ []int {y2 , x1 , x2 , - 1 },
66
+ )
67
+ }
68
+
69
+ // 对 labels 进行排序
70
+ sort .Slice (labels , func (i int , j int ) bool {
71
+ eq0 := labels [i ][0 ] == labels [j ][0 ]
72
+ eq1 := labels [i ][1 ] == labels [j ][1 ]
73
+ eq2 := labels [i ][2 ] == labels [j ][2 ]
74
+ if eq0 && eq1 && eq2 {
75
+ return labels [i ][3 ] < labels [j ][3 ]
76
+ }
77
+ if eq0 && eq1 {
78
+ return labels [i ][2 ] < labels [j ][2 ]
79
+ }
80
+ if eq0 {
81
+ return labels [i ][1 ] < labels [j ][1 ]
82
+ }
83
+ return labels [i ][0 ] < labels [j ][0 ]
84
+ })
85
+
86
+ return labels
87
+ }
0 commit comments