LeetCode-in-Java

3453. Separate Squares I

Medium

You are given a 2D integer array squares. Each squares[i] = [xi, yi, li] 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 of the squares above the line equals the total area of the squares below the line.

Answers within 10-5 of the actual answer will be accepted.

Note: Squares may overlap. Overlapping areas should be counted multiple times.

Example 1:

Input: squares = [[0,0,1],[2,2,1]]

Output: 1.00000

Explanation:

Any horizontal line between y = 1 and y = 2 will have 1 square unit above it and 1 square unit below it. The lowest option is 1.

Example 2:

Input: squares = [[0,0,2],[1,1,1]]

Output: 1.16667

Explanation:

The areas are:

Since the areas above and below the line are equal, the output is 7/6 = 1.16667.

Constraints:

Solution

public class Solution {
    public double separateSquares(int[][] squares) {
        long hi = 0L;
        long lo = 1_000_000_000L;
        for (int[] q : squares) {
            lo = Math.min(lo, q[1]);
            hi = Math.max(hi, q[1] + (long) q[2]);
        }
        while (lo <= hi) {
            long mid = (lo + hi) / 2;
            if (diff(mid, squares) <= 0) {
                hi = mid - 1;
            } else {
                lo = mid + 1;
            }
        }
        double diff1 = diff(hi, squares);
        double diff2 = diff(lo, squares);
        return hi + diff1 / (diff1 - diff2);
    }

    private double diff(long mid, int[][] squares) {
        double[] res = new double[2];
        for (int[] q : squares) {
            res[0] += Math.min(q[2], Math.max(0, mid - q[1])) * q[2];
            res[1] += Math.min(q[2], Math.max(0, q[1] + q[2] - mid)) * q[2];
        }
        return res[1] - res[0];
    }
}