diff --git a/solution/0400-0499/0447.Number of Boomerangs/README.md b/solution/0400-0499/0447.Number of Boomerangs/README.md index 4ef4fe7141c00..41fda5e321e0e 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/README.md +++ b/solution/0400-0499/0447.Number of Boomerangs/README.md @@ -49,9 +49,13 @@ -计数器实现。 +**方法一:枚举 + 计数** -对于每个点,计算其他点到该点的距离,然后按照距离进行分组计数。对每个组中的点进行两两排列组合(A n 取 2,即 `n * (n - 1))`)计数即可。 +我们可以枚举 `points` 中的每个点作为回旋镖的点 $i$,然后用一个哈希表 $cnt$ 记录其他点到 $i$ 的距离出现的次数。 + +如果有 $x$ 个点到 $i$ 的距离相等,那么我们可以任选其中 $2$ 个点作为回旋镖的 $j$ 和 $k$,方案数为 $A_x^2 = x \times (x - 1)$。因此,我们对哈希表中的每个值 $x$,都计算并累加 $A_x^2$,就可以得到满足题目要求的回旋镖数量之和。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `points` 的长度。 @@ -63,12 +67,25 @@ class Solution: def numberOfBoomerangs(self, points: List[List[int]]) -> int: ans = 0 - for p in points: - counter = Counter() - for q in points: - distance = (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]) - counter[distance] += 1 - ans += sum([val * (val - 1) for val in counter.values()]) + for p1 in points: + cnt = Counter() + for p2 in points: + d = dist(p1, p2) + ans += cnt[d] + cnt[d] += 1 + return ans << 1 +``` + +```python +class Solution: + def numberOfBoomerangs(self, points: List[List[int]]) -> int: + ans = 0 + for p1 in points: + cnt = Counter() + for p2 in points: + d = dist(p1, p2) + cnt[d] += 1 + ans += sum(x * (x - 1) for x in cnt.values()) return ans ``` @@ -80,72 +97,71 @@ class Solution: class Solution { public int numberOfBoomerangs(int[][] points) { int ans = 0; - for (int[] p : points) { - Map counter = new HashMap<>(); - for (int[] q : points) { - int distance = (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]); - counter.put(distance, counter.getOrDefault(distance, 0) + 1); - } - for (int val : counter.values()) { - ans += val * (val - 1); + for (int[] p1 : points) { + Map cnt = new HashMap<>(); + for (int[] p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + ans += cnt.getOrDefault(d, 0); + cnt.merge(d, 1, Integer::sum); } } - return ans; + return ans << 1; } } ``` -### **TypeScript** - -```ts -function numberOfBoomerangs(points: number[][]): number { - let ans = 0; - for (let p1 of points) { - let hashMap: Map = new Map(); - for (let p2 of points) { - const distance = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2; - hashMap.set(distance, (hashMap.get(distance) || 0) + 1); - } - for (let [, v] of [...hashMap]) { - ans += v * (v - 1); +```java +class Solution { + public int numberOfBoomerangs(int[][] points) { + int ans = 0; + for (int[] p1 : points) { + Map cnt = new HashMap<>(); + for (int[] p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + cnt.merge(d, 1, Integer::sum); + } + for (int x : cnt.values()) { + ans += x * (x - 1); + } } + return ans; } - return ans; } ``` -### **Go** +### **C++** -```go -func numberOfBoomerangs(points [][]int) int { - ans := 0 - for _, p := range points { - cnt := make(map[int]int) - for _, q := range points { - cnt[(p[0]-q[0])*(p[0]-q[0])+(p[1]-q[1])*(p[1]-q[1])]++ - } - for _, v := range cnt { - ans += v * (v - 1) - } - } - return ans -} +```cpp +class Solution { +public: + int numberOfBoomerangs(vector>& points) { + int ans = 0; + for (auto& p1 : points) { + unordered_map cnt; + for (auto& p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + ans += cnt[d]; + cnt[d]++; + } + } + return ans << 1; + } +}; ``` -### **C++** - ```cpp class Solution { public: int numberOfBoomerangs(vector>& points) { int ans = 0; - for (const auto& p : points) { + for (auto& p1 : points) { unordered_map cnt; - for (const auto& q : points) { - ++cnt[(p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1])]; + for (auto& p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + cnt[d]++; } - for (const auto& [_, v] : cnt) { - ans += v * (v - 1); + for (auto& [_, x] : cnt) { + ans += x * (x - 1); } } return ans; @@ -153,6 +169,73 @@ public: }; ``` +### **Go** + +```go +func numberOfBoomerangs(points [][]int) (ans int) { + for _, p1 := range points { + cnt := map[int]int{} + for _, p2 := range points { + d := (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + ans += cnt[d] + cnt[d]++ + } + } + ans <<= 1 + return +} +``` + +```go +func numberOfBoomerangs(points [][]int) (ans int) { + for _, p1 := range points { + cnt := map[int]int{} + for _, p2 := range points { + d := (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + cnt[d]++ + } + for _, x := range cnt { + ans += x * (x - 1) + } + } + return +} +``` + +### **TypeScript** + +```ts +function numberOfBoomerangs(points: number[][]): number { + let ans = 0; + for (const [x1, y1] of points) { + const cnt: Map = new Map(); + for (const [x2, y2] of points) { + const d = (x1 - x2) ** 2 + (y1 - y2) ** 2; + ans += cnt.get(d) || 0; + cnt.set(d, (cnt.get(d) || 0) + 1); + } + } + return ans << 1; +} +``` + +```ts +function numberOfBoomerangs(points: number[][]): number { + let ans = 0; + for (const [x1, y1] of points) { + const cnt: Map = new Map(); + for (const [x2, y2] of points) { + const d = (x1 - x2) ** 2 + (y1 - y2) ** 2; + cnt.set(d, (cnt.get(d) || 0) + 1); + } + for (const [_, x] of cnt) { + ans += x * (x - 1); + } + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/0400-0499/0447.Number of Boomerangs/README_EN.md b/solution/0400-0499/0447.Number of Boomerangs/README_EN.md index edfd91250fb8d..10f1d0d2bbee2 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/README_EN.md +++ b/solution/0400-0499/0447.Number of Boomerangs/README_EN.md @@ -44,6 +44,14 @@ ## Solutions +**Solution 1: Enumeration + Counting** + +We can enumerate each point in `points` as the boomerang's point $i$, and then use a hash table $cnt$ to record the number of times the distance from other points to $i$ appears. + +If there are $x$ points with equal distance to $i$, then we can arbitrarily select two of them as the boomerang's $j$ and $k$. The number of schemes is $A_x^2 = x \times (x - 1)$. Therefore, for each value $x$ in the hash table, we calculate and accumulate $A_x^2$, which gives us the total number of boomerangs that meet the problem's requirements. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$, where $n$ is the length of the array `points`. + ### **Python3** @@ -52,12 +60,25 @@ class Solution: def numberOfBoomerangs(self, points: List[List[int]]) -> int: ans = 0 - for p in points: - counter = Counter() - for q in points: - distance = (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]) - counter[distance] += 1 - ans += sum([val * (val - 1) for val in counter.values()]) + for p1 in points: + cnt = Counter() + for p2 in points: + d = dist(p1, p2) + ans += cnt[d] + cnt[d] += 1 + return ans << 1 +``` + +```python +class Solution: + def numberOfBoomerangs(self, points: List[List[int]]) -> int: + ans = 0 + for p1 in points: + cnt = Counter() + for p2 in points: + d = dist(p1, p2) + cnt[d] += 1 + ans += sum(x * (x - 1) for x in cnt.values()) return ans ``` @@ -67,72 +88,71 @@ class Solution: class Solution { public int numberOfBoomerangs(int[][] points) { int ans = 0; - for (int[] p : points) { - Map counter = new HashMap<>(); - for (int[] q : points) { - int distance = (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]); - counter.put(distance, counter.getOrDefault(distance, 0) + 1); - } - for (int val : counter.values()) { - ans += val * (val - 1); + for (int[] p1 : points) { + Map cnt = new HashMap<>(); + for (int[] p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + ans += cnt.getOrDefault(d, 0); + cnt.merge(d, 1, Integer::sum); } } - return ans; + return ans << 1; } } ``` -### **TypeScript** - -```ts -function numberOfBoomerangs(points: number[][]): number { - let ans = 0; - for (let p1 of points) { - let hashMap: Map = new Map(); - for (let p2 of points) { - const distance = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2; - hashMap.set(distance, (hashMap.get(distance) || 0) + 1); - } - for (let [, v] of [...hashMap]) { - ans += v * (v - 1); +```java +class Solution { + public int numberOfBoomerangs(int[][] points) { + int ans = 0; + for (int[] p1 : points) { + Map cnt = new HashMap<>(); + for (int[] p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + cnt.merge(d, 1, Integer::sum); + } + for (int x : cnt.values()) { + ans += x * (x - 1); + } } + return ans; } - return ans; } ``` -### **Go** +### **C++** -```go -func numberOfBoomerangs(points [][]int) int { - ans := 0 - for _, p := range points { - cnt := make(map[int]int) - for _, q := range points { - cnt[(p[0]-q[0])*(p[0]-q[0])+(p[1]-q[1])*(p[1]-q[1])]++ - } - for _, v := range cnt { - ans += v * (v - 1) - } - } - return ans -} +```cpp +class Solution { +public: + int numberOfBoomerangs(vector>& points) { + int ans = 0; + for (auto& p1 : points) { + unordered_map cnt; + for (auto& p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + ans += cnt[d]; + cnt[d]++; + } + } + return ans << 1; + } +}; ``` -### **C++** - ```cpp class Solution { public: int numberOfBoomerangs(vector>& points) { int ans = 0; - for (const auto& p : points) { + for (auto& p1 : points) { unordered_map cnt; - for (const auto& q : points) { - ++cnt[(p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1])]; + for (auto& p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + cnt[d]++; } - for (const auto& [_, v] : cnt) { - ans += v * (v - 1); + for (auto& [_, x] : cnt) { + ans += x * (x - 1); } } return ans; @@ -140,6 +160,73 @@ public: }; ``` +### **Go** + +```go +func numberOfBoomerangs(points [][]int) (ans int) { + for _, p1 := range points { + cnt := map[int]int{} + for _, p2 := range points { + d := (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + ans += cnt[d] + cnt[d]++ + } + } + ans <<= 1 + return +} +``` + +```go +func numberOfBoomerangs(points [][]int) (ans int) { + for _, p1 := range points { + cnt := map[int]int{} + for _, p2 := range points { + d := (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + cnt[d]++ + } + for _, x := range cnt { + ans += x * (x - 1) + } + } + return +} +``` + +### **TypeScript** + +```ts +function numberOfBoomerangs(points: number[][]): number { + let ans = 0; + for (const [x1, y1] of points) { + const cnt: Map = new Map(); + for (const [x2, y2] of points) { + const d = (x1 - x2) ** 2 + (y1 - y2) ** 2; + ans += cnt.get(d) || 0; + cnt.set(d, (cnt.get(d) || 0) + 1); + } + } + return ans << 1; +} +``` + +```ts +function numberOfBoomerangs(points: number[][]): number { + let ans = 0; + for (const [x1, y1] of points) { + const cnt: Map = new Map(); + for (const [x2, y2] of points) { + const d = (x1 - x2) ** 2 + (y1 - y2) ** 2; + cnt.set(d, (cnt.get(d) || 0) + 1); + } + for (const [_, x] of cnt) { + ans += x * (x - 1); + } + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/0400-0499/0447.Number of Boomerangs/Solution.cpp b/solution/0400-0499/0447.Number of Boomerangs/Solution.cpp index a995317d75c56..4bb88388639f6 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/Solution.cpp +++ b/solution/0400-0499/0447.Number of Boomerangs/Solution.cpp @@ -1,16 +1,17 @@ -class Solution { -public: - int numberOfBoomerangs(vector>& points) { - int ans = 0; - for (const auto& p : points) { - unordered_map cnt; - for (const auto& q : points) { - ++cnt[(p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1])]; - } - for (const auto& [_, v] : cnt) { - ans += v * (v - 1); - } - } - return ans; - } -}; +class Solution { +public: + int numberOfBoomerangs(vector>& points) { + int ans = 0; + for (auto& p1 : points) { + unordered_map cnt; + for (auto& p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + cnt[d]++; + } + for (auto& [_, x] : cnt) { + ans += x * (x - 1); + } + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/0400-0499/0447.Number of Boomerangs/Solution.go b/solution/0400-0499/0447.Number of Boomerangs/Solution.go index 39a064c0272eb..7ce75d48352ac 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/Solution.go +++ b/solution/0400-0499/0447.Number of Boomerangs/Solution.go @@ -1,13 +1,13 @@ -func numberOfBoomerangs(points [][]int) int { - ans := 0 - for _, p := range points { - cnt := make(map[int]int) - for _, q := range points { - cnt[(p[0]-q[0])*(p[0]-q[0])+(p[1]-q[1])*(p[1]-q[1])]++ +func numberOfBoomerangs(points [][]int) (ans int) { + for _, p1 := range points { + cnt := map[int]int{} + for _, p2 := range points { + d := (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + cnt[d]++ } - for _, v := range cnt { - ans += v * (v - 1) + for _, x := range cnt { + ans += x * (x - 1) } } - return ans + return } \ No newline at end of file diff --git a/solution/0400-0499/0447.Number of Boomerangs/Solution.java b/solution/0400-0499/0447.Number of Boomerangs/Solution.java index 7149ab65c9d1e..eb6e8377486c7 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/Solution.java +++ b/solution/0400-0499/0447.Number of Boomerangs/Solution.java @@ -1,16 +1,16 @@ -class Solution { - public int numberOfBoomerangs(int[][] points) { - int ans = 0; - for (int[] p : points) { - Map counter = new HashMap<>(); - for (int[] q : points) { - int distance = (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]); - counter.put(distance, counter.getOrDefault(distance, 0) + 1); - } - for (int val : counter.values()) { - ans += val * (val - 1); - } - } - return ans; - } +class Solution { + public int numberOfBoomerangs(int[][] points) { + int ans = 0; + for (int[] p1 : points) { + Map cnt = new HashMap<>(); + for (int[] p2 : points) { + int d = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]); + cnt.merge(d, 1, Integer::sum); + } + for (int x : cnt.values()) { + ans += x * (x - 1); + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/0400-0499/0447.Number of Boomerangs/Solution.py b/solution/0400-0499/0447.Number of Boomerangs/Solution.py index fb9c7b6894ce4..44ab8946074cc 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/Solution.py +++ b/solution/0400-0499/0447.Number of Boomerangs/Solution.py @@ -1,10 +1,10 @@ -class Solution: - def numberOfBoomerangs(self, points: List[List[int]]) -> int: - ans = 0 - for p in points: - counter = Counter() - for q in points: - distance = (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]) - counter[distance] += 1 - ans += sum([val * (val - 1) for val in counter.values()]) - return ans +class Solution: + def numberOfBoomerangs(self, points: List[List[int]]) -> int: + ans = 0 + for p1 in points: + cnt = Counter() + for p2 in points: + d = dist(p1, p2) + cnt[d] += 1 + ans += sum(x * (x - 1) for x in cnt.values()) + return ans diff --git a/solution/0400-0499/0447.Number of Boomerangs/Solution.ts b/solution/0400-0499/0447.Number of Boomerangs/Solution.ts index 20daebc0130ae..6c45ef22118e4 100644 --- a/solution/0400-0499/0447.Number of Boomerangs/Solution.ts +++ b/solution/0400-0499/0447.Number of Boomerangs/Solution.ts @@ -1,13 +1,13 @@ function numberOfBoomerangs(points: number[][]): number { let ans = 0; - for (let p1 of points) { - let hashMap: Map = new Map(); - for (let p2 of points) { - const distance = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2; - hashMap.set(distance, (hashMap.get(distance) || 0) + 1); + for (const [x1, y1] of points) { + const cnt: Map = new Map(); + for (const [x2, y2] of points) { + const d = (x1 - x2) ** 2 + (y1 - y2) ** 2; + cnt.set(d, (cnt.get(d) || 0) + 1); } - for (let [, v] of [...hashMap]) { - ans += v * (v - 1); + for (const [_, x] of cnt) { + ans += x * (x - 1); } } return ans;