题目:
给你一个二维整数数组 rectangles ,其中 rectangles[i] = [li, hi] 表示第 i 个矩形长为 li 高为 hi 。给你一个二维整数数组 points ,其中 points[j] = [xj, yj] 是坐标为 (xj, yj) 的一个点。
第 i 个矩形的 左下角 在 (0, 0) 处,右上角 在 (li, hi) 。
请你返回一个整数数组 **count ,长度为 points.length,其中 **count[j]是 包含 第 **j 个点的矩形数目。
如果 0 <= xj <= li 且 0 <= yj <= hi ,那么我们说第 i 个矩形包含第 j 个点。如果一个点刚好在矩形的 边上 ,这个点也被视为被矩形包含。
算法:
方法一:排序
二维统计数量的小技巧,recCount
func countRectangles(rectangles [][]int, points [][]int) []int {
n := len(points)
// rectangles, points升序排序
sort.Slice(rectangles, func(i, j int) bool {return rectangles[i][0] < rectangles[j][0]})
for i := range points {
points[i] = append(points[i], i)
}
sort.Slice(points, func(i, j int) bool {return points[i][0] < points[j][0]})
// count[i] 大于等于当前point的x坐标,且纵坐标y=j的rectangle数目
recCount := make([]int, 101)
j := len(rectangles) - 1
ans := make([]int, n)
for i := n - 1; i >= 0; i -- {
// recCount[i],大于等于当前point x坐标的y=i坐标个数放到recCount中
for ; j >= 0 && points[i][0] <= rectangles[j][0] ; j-- {
recCount[rectangles[j][1]] ++
}
// 统计当前遍历到的y坐标大于等于points[i][1]的个数
for _, c := range recCount[points[i][1]:] {
ans[points[i][2]] = ans[points[i][2]] + c
}
}
return ans
}
方法二:横坐标排序
func countRectangles(rectangles [][]int, points [][]int) []int {
highLengths := make([][]int, 101)
for i := range rectangles {
highLengths[rectangles[i][1]] = append(highLengths[rectangles[i][1]], rectangles[i][0])
}
// 对每个横坐标排序
for i := range highLengths {
sort.Ints(highLengths[i])
}
ans := make([]int, len(points))
for i := range points {
for j := points[i][1]; j < len(highLengths); j ++ {
ans[i] = ans[i] + len(highLengths[j]) - findLowBound(highLengths[j], points[i][0])
}
}
return ans
}
// 找到小于等于x的数在list的下标,如果没有的话下标就是0
func findLowBound(list []int, x int) int {
left, right := 0, len(list) - 1
for left <= right {
mid := (left + right) / 2
if list[mid] < x {
left = mid + 1
} else {
right = mid - 1
}
}
return left
}