Welcome to Subscribe On Youtube
3625. Count Number of Trapezoids II
Description
You are given a 2D integer array points where points[i] = [xi, yi] represents the coordinates of the ith point on the Cartesian plane.
Return the number of unique trapezoids that can be formed by choosing any four distinct points from points.
A trapezoid is a convex quadrilateral with at least one pair of parallel sides. Two lines are parallel if and only if they have the same slope.
Example 1:
Input: points = [[-3,2],[3,0],[2,3],[3,2],[2,-3]]
Output: 2
Explanation:

There are two distinct ways to pick four points that form a trapezoid:
- The points
[-3,2], [2,3], [3,2], [2,-3]form one trapezoid. - The points
[2,3], [3,2], [3,0], [2,-3]form another trapezoid.
Example 2:
Input: points = [[0,0],[1,0],[0,1],[2,1]]
Output: 1
Explanation:

There is only one trapezoid which can be formed.
Constraints:
4 <= points.length <= 500–1000 <= xi, yi <= 1000- All points are pairwise distinct.
Solutions
Solution 1
-
class Solution { public int countTrapezoids(int[][] points) { int n = points.length; Map<Double, Map<Double, Integer>> cnt1 = new HashMap<>(n * n); Map<Integer, Map<Double, Integer>> cnt2 = new HashMap<>(n * n); for (int i = 0; i < n; ++i) { int x1 = points[i][0], y1 = points[i][1]; for (int j = 0; j < i; ++j) { int x2 = points[j][0], y2 = points[j][1]; int dx = x2 - x1, dy = y2 - y1; double k = dx == 0 ? Double.MAX_VALUE : 1.0 * dy / dx; double b = dx == 0 ? x1 : 1.0 * (y1 * dx - x1 * dy) / dx; if (k == -0.0) { k = 0.0; } if (b == -0.0) { b = 0.0; } cnt1.computeIfAbsent(k, _ -> new HashMap<>()).merge(b, 1, Integer::sum); int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); cnt2.computeIfAbsent(p, _ -> new HashMap<>()).merge(k, 1, Integer::sum); } } int ans = 0; for (var e : cnt1.values()) { int s = 0; for (int t : e.values()) { ans += s * t; s += t; } } for (var e : cnt2.values()) { int s = 0; for (int t : e.values()) { ans -= s * t; s += t; } } return ans; } } -
class Solution { public: int countTrapezoids(vector<vector<int>>& points) { int n = points.size(); unordered_map<double, unordered_map<double, int>> cnt1; unordered_map<int, unordered_map<double, int>> cnt2; cnt1.reserve(n * n); cnt2.reserve(n * n); for (int i = 0; i < n; ++i) { int x1 = points[i][0], y1 = points[i][1]; for (int j = 0; j < i; ++j) { int x2 = points[j][0], y2 = points[j][1]; int dx = x2 - x1, dy = y2 - y1; double k = (dx == 0 ? 1e9 : 1.0 * dy / dx); double b = (dx == 0 ? x1 : 1.0 * (1LL * y1 * dx - 1LL * x1 * dy) / dx); cnt1[k][b] += 1; int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); cnt2[p][k] += 1; } } int ans = 0; for (auto& [_, e] : cnt1) { int s = 0; for (auto& [_, t] : e) { ans += s * t; s += t; } } for (auto& [_, e] : cnt2) { int s = 0; for (auto& [_, t] : e) { ans -= s * t; s += t; } } return ans; } }; -
class Solution: def countTrapezoids(self, points: List[List[int]]) -> int: n = len(points) # cnt1: k -> (b -> count) cnt1: dict[float, dict[float, int]] = defaultdict(lambda: defaultdict(int)) # cnt2: p -> (k -> count) cnt2: dict[int, dict[float, int]] = defaultdict(lambda: defaultdict(int)) for i in range(n): x1, y1 = points[i] for j in range(i): x2, y2 = points[j] dx, dy = x2 - x1, y2 - y1 if dx == 0: k = 1e9 b = x1 else: k = dy / dx b = (y1 * dx - x1 * dy) / dx cnt1[k][b] += 1 p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000) cnt2[p][k] += 1 ans = 0 for e in cnt1.values(): s = 0 for t in e.values(): ans += s * t s += t for e in cnt2.values(): s = 0 for t in e.values(): ans -= s * t s += t return ans -
func countTrapezoids(points [][]int) int { n := len(points) cnt1 := make(map[float64]map[float64]int, n*n) cnt2 := make(map[int]map[float64]int, n*n) for i := 0; i < n; i++ { x1, y1 := points[i][0], points[i][1] for j := 0; j < i; j++ { x2, y2 := points[j][0], points[j][1] dx, dy := x2-x1, y2-y1 var k, b float64 if dx == 0 { k = 1e9 b = float64(x1) } else { k = float64(dy) / float64(dx) b = float64(int64(y1)*int64(dx)-int64(x1)*int64(dy)) / float64(dx) } if cnt1[k] == nil { cnt1[k] = make(map[float64]int) } cnt1[k][b]++ p := (x1+x2+2000)*4000 + (y1 + y2 + 2000) if cnt2[p] == nil { cnt2[p] = make(map[float64]int) } cnt2[p][k]++ } } ans := 0 for _, e := range cnt1 { s := 0 for _, t := range e { ans += s * t s += t } } for _, e := range cnt2 { s := 0 for _, t := range e { ans -= s * t s += t } } return ans } -
function countTrapezoids(points: number[][]): number { const n = points.length; const cnt1: Map<number, Map<number, number>> = new Map(); const cnt2: Map<number, Map<number, number>> = new Map(); for (let i = 0; i < n; i++) { const [x1, y1] = points[i]; for (let j = 0; j < i; j++) { const [x2, y2] = points[j]; const [dx, dy] = [x2 - x1, y2 - y1]; const k = dx === 0 ? 1e9 : dy / dx; const b = dx === 0 ? x1 : (y1 * dx - x1 * dy) / dx; if (!cnt1.has(k)) { cnt1.set(k, new Map()); } const mapB = cnt1.get(k)!; mapB.set(b, (mapB.get(b) || 0) + 1); const p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); if (!cnt2.has(p)) { cnt2.set(p, new Map()); } const mapK = cnt2.get(p)!; mapK.set(k, (mapK.get(k) || 0) + 1); } } let ans = 0; for (const e of cnt1.values()) { let s = 0; for (const t of e.values()) { ans += s * t; s += t; } } for (const e of cnt2.values()) { let s = 0; for (const t of e.values()) { ans -= s * t; s += t; } } return ans; }