Skip to content

Commit 5cbbed6

Browse files
chore: add LeetCode daily solution
1 parent b7ac6b5 commit 5cbbed6

File tree

5 files changed

+141
-0
lines changed

5 files changed

+141
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Count Number of Trapezoids II (Hard)
2+
3+
**Problem ID:** 3625
4+
**Date:** 2025-12-03
5+
**Link:** https://leetcode.com/problems/count-number-of-trapezoids-ii/
6+
7+
## Approach
8+
9+
To solve the problem of counting unique trapezoids that can be formed from a set of points on a Cartesian plane, we can follow a systematic approach based on the properties of trapezoids and the concept of slopes.
10+
11+
### Main Idea:
12+
A trapezoid is defined as a convex quadrilateral with at least one pair of parallel sides. To identify trapezoids from a set of points, we can leverage the fact that two sides are parallel if they have the same slope. Therefore, the key steps involve calculating the slopes between pairs of points and grouping points that share the same slope.
13+
14+
### Approach:
15+
1. **Calculate Slopes**: For each pair of points, compute the slope. The slope between two points \((x_1, y_1)\) and \((x_2, y_2)\) can be represented as a fraction \((y_2 - y_1) / (x_2 - x_1)\). To avoid floating-point inaccuracies and division by zero, we can represent slopes as pairs of integers (dy, dx) reduced to their simplest form using the greatest common divisor (GCD).
16+
17+
2. **Group Points by Slopes**: Use a dictionary to group points that share the same slope. For each point, maintain a mapping of slopes to the list of points that can be reached from it with that slope.
18+
19+
3. **Count Trapezoids**: For each unique slope group, if there are \(n\) points that share the same slope, we can choose any two points from these \(n\) points to form one pair of parallel sides. The number of ways to choose 2 points from \(n\) is given by \(\binom{n}{2} = n(n-1)/2\). For each pair of parallel sides, we need to find points from the other slope groups to form the remaining two sides of the trapezoid.
20+
21+
4. **Combine Results**: For each combination of two pairs of parallel sides (from different slope groups), check if they can form a trapezoid and count them.
22+
23+
### Data Structures:
24+
- A dictionary (or hashmap) to store slopes as keys and lists of points as values.
25+
- A set to keep track of unique trapezoids to avoid counting duplicates.
26+
27+
### Complexity:
28+
- **Time Complexity**: The algorithm primarily involves iterating through pairs of points to calculate slopes, leading to a time complexity of \(O(n^2)\), where \(n\) is the number of points. The subsequent operations to count trapezoids depend on the number of unique slopes and points associated with them.
29+
- **Space Complexity**: The space complexity is \(O(n)\) for storing the points in the slope dictionary.
30+
31+
This approach effectively reduces the problem to manageable components by focusing on the geometric properties of trapezoids and utilizing combinatorial counting, thus allowing us to efficiently count the number of unique trapezoids formed by the given points.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class Solution {
5+
public int countTrapezoids(int[][] points) {
6+
int n = points.length;
7+
Map<Integer, Map<Integer, Integer>> slopeCount = new HashMap<>();
8+
int trapezoidCount = 0;
9+
10+
for (int i = 0; i < n; i++) {
11+
for (int j = i + 1; j < n; j++) {
12+
if (points[i][1] != points[j][1]) {
13+
int dx = points[j][0] - points[i][0];
14+
int dy = points[j][1] - points[i][1];
15+
int gcd = gcd(dx, dy);
16+
dx /= gcd;
17+
dy /= gcd;
18+
19+
slopeCount.putIfAbsent(dy, new HashMap<>());
20+
slopeCount.get(dy).putIfAbsent(dx, 0);
21+
slopeCount.get(dy).put(dx, slopeCount.get(dy).get(dx) + 1);
22+
}
23+
}
24+
}
25+
26+
for (Map<Integer, Integer> map : slopeCount.values()) {
27+
for (int count : map.values()) {
28+
if (count >= 2) {
29+
trapezoidCount += count * (count - 1) / 2;
30+
}
31+
}
32+
}
33+
34+
return trapezoidCount;
35+
}
36+
37+
private int gcd(int a, int b) {
38+
while (b != 0) {
39+
int temp = b;
40+
b = a % b;
41+
a = temp;
42+
}
43+
return a;
44+
}
45+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
var countTrapezoids = function(points) {
2+
const slopes = new Map();
3+
const n = points.length;
4+
5+
for (let i = 0; i < n; i++) {
6+
for (let j = i + 1; j < n; j++) {
7+
const dx = points[j][0] - points[i][0];
8+
const dy = points[j][1] - points[i][1];
9+
const gcd = getGCD(dx, dy);
10+
const slope = `${dy / gcd},${dx / gcd}`;
11+
if (!slopes.has(slope)) {
12+
slopes.set(slope, new Set());
13+
}
14+
slopes.get(slope).add(`${points[i][0]},${points[i][1]}`);
15+
slopes.get(slope).add(`${points[j][0]},${points[j][1]}`);
16+
}
17+
}
18+
19+
let count = 0;
20+
for (const set of slopes.values()) {
21+
const size = set.size;
22+
if (size >= 4) {
23+
count += (size * (size - 1) * (size - 2) * (size - 3)) / 24;
24+
}
25+
}
26+
27+
return count;
28+
};
29+
30+
function getGCD(a, b) {
31+
while (b) {
32+
[a, b] = [b, a % b];
33+
}
34+
return a;
35+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from collections import defaultdict
2+
from itertools import combinations
3+
4+
class Solution:
5+
def countTrapezoids(self, points: List[List[int]]) -> int:
6+
slopes = defaultdict(set)
7+
n = len(points)
8+
9+
for i in range(n):
10+
for j in range(i + 1, n):
11+
if points[i][0] != points[j][0]: # Avoid vertical lines
12+
slope = (points[j][1] - points[i][1], points[j][0] - points[i][0])
13+
gcd = self.gcd(slope[0], slope[1])
14+
slope = (slope[0] // gcd, slope[1] // gcd)
15+
slopes[slope].add((i, j))
16+
17+
trapezoid_count = 0
18+
19+
for pairs in slopes.values():
20+
m = len(pairs)
21+
if m >= 2:
22+
trapezoid_count += m * (m - 1) // 2
23+
24+
return trapezoid_count
25+
26+
def gcd(self, a: int, b: int) -> int:
27+
while b:
28+
a, b = b, a % b
29+
return abs(a)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,4 @@ Through completing the Blind 75 and NeetCode 150, you will have mastered:
293293
- 2025-11-30 — [Make Sum Divisible by P](https://leetcode.com/problems/make-sum-divisible-by-p/) (Medium) → `Medium/2025-11-30-1590-Make-Sum-Divisible-by-P`
294294
- 2025-12-01 — [Maximum Running Time of N Computers](https://leetcode.com/problems/maximum-running-time-of-n-computers/) (Hard) → `Hard/2025-12-01-2141-Maximum-Running-Time-of-N-Computers`
295295
- 2025-12-02 — [Count Number of Trapezoids I](https://leetcode.com/problems/count-number-of-trapezoids-i/) (Medium) → `Medium/2025-12-02-3623-Count-Number-of-Trapezoids-I`
296+
- 2025-12-03 — [Count Number of Trapezoids II](https://leetcode.com/problems/count-number-of-trapezoids-ii/) (Hard) → `Hard/2025-12-03-3625-Count-Number-of-Trapezoids-II`

0 commit comments

Comments
 (0)