leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

separate_sqaures2.py (2450B)


# 3454. Separate Squares II

"""
you are given a 2d integer array 'squares'. each 'squares[i] = [xi, yi, zi]'
represents the coordinates of the bottom left point and the side length of a
square parallel to the x-axis. find the minimum y-coordinate value of a
horizontal line such that the total area covered by squares above the line
equal the total area covered by squares below the line. answers within 10^-5
of the actual answer will be accepted. note: squares may overlap. overlapping
areas should be counted only once in this version.
"""


class Solution(object):
    def separateSquares(self, squares):
        """
        :type squares: List[List[int]]
        :rtype: float
        """
        events = []
        for x, y, l in squares:
            events.append((y, 1, x, x + l))
            events.append((y + l, -1, x, x + l))
        events.sort()
        active_intervals = []
        prev_y = events[0][0]
        total_area = 0
        horizontal_slices = []

        def union_width(intervals):
            intervals.sort()
            total_width = 0
            rightmost = float("-inf")
            for left, right in intervals:
                if left > rightmost:
                    total_width += right - left
                    rightmost = right
                elif right > rightmost:
                    total_width += right - rightmost
                    rightmost = right
            return total_width

        for y, event_type, x_left, x_right in events:
            if y > prev_y and active_intervals:
                height = y - prev_y
                width = union_width(active_intervals)
                horizontal_slices.append((prev_y, height, width))
                total_area += height * width
            if event_type == 1:
                active_intervals.append((x_left, x_right))
            else:
                active_intervals.remove((x_left, x_right))
            prev_y = y
        half_area = total_area / 2
        accumulated = 0
        for start_y, height, width in horizontal_slices:
            slice_area = height * width
            if accumulated + slice_area >= half_area:
                return start_y + (half_area - accumulated) / width
            accumulated += slice_area
        return float(prev_y)


if __name__ == "__main__":
    obj = Solution()
    print(obj.separateSquares(squares=[[0, 0, 1], [2, 2, 1]]))
    print(obj.separateSquares(squares=[[0, 0, 2], [1, 1, 1]]))