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

76 阅读1分钟

题目:
给你一个二维整数数组 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
}