Find the Number of Ways to Place People I

Medium
Watch on YouTube ↗

Solution

/*--------------- Brute Force Solution ---------------*/
class Solution {
    public int numberOfPairs(int[][] points) {
        int n = points.length;
        int ans = 0;
        for(int i=0; i<n; i++) {
            int x1 = points[i][0], y1 = points[i][1];
            for(int j=0; j<n; j++) {
                if(i==j)
                    continue;
                int x2 = points[j][0], y2 = points[j][1];
                // point i does not lie in left
                if(x1 > x2) 
                    continue;
                // point i does not lie in top
                if(y1 < y2)
                    continue;
                boolean blocked = false;
                for(int k=0; k<n; k++) {
                    if(k==i || k==j)
                        continue; 
                    int xk = points[k][0], yk = points[k][1];
                    if(x1<=xk && xk<=x2 && y2<=yk && yk<=y1)
                    {
                        blocked = true;
                        break;
                    }
                }
                if(!blocked) 
                    ans++;
            }
        }
        return ans;
  }
}

/*--------------- Optimal Solution ---------------*/

class Solution {
    public int numberOfPairs(int[][] points) {
        int n = points.length;
        int ans = 0;

        // Sort points by x-coordinate (ascending).
        // If x is the same, sort by y-coordinate (descending).
        Arrays.sort(points, (a, b) -> {
            if (a[0] == b[0]) {
                return b[1] - a[1]; 
            }
            return a[0] - b[0];
        });

        // Iterate over each point as the "left" point in the pair
        for (int i = 0; i < n; i++) {
            int x1 = points[i][0], y1 = points[i][1];
            
            // Keeps track of the maximum y encountered so far (to avoid duplicates)
            int maxY = Integer.MIN_VALUE;

            // Compare with points to the right (greater x)
            for (int j = i + 1; j < n; j++) {
                int x2 = points[j][0], y2 = points[j][1];

                // Valid pair only if y2 <= y1 (point j is below or equal in height)
                if (y2 > y1) continue;

                // Ensure uniqueness: only count if y2 is greater than all previously seen y2
                if (y2 > maxY) {
                    ans++;
                    maxY = y2;
                }
            }
        }

        return ans;
    }
}




/*
Solution Explaination Notes:
1. x1 < x2  and y2 <= y1 (second point is not higher in y)
2. or if x1 == x2, then y1 > y2


(1, 4), (2, 3), (3, 2), (4, 1), (2, 5)

y

6 |                        
5 |        ● (2,5)
4 |    ● (1,4)
3 |        ● (2,3)
2 |            ● (3,2)
1 |                ● (4,1)
0 |__________________________________________→ x
    0    1    2    3    4    5


*/