|
59 | 59 |
|
60 | 60 | <!-- 这里可写通用的实现逻辑 -->
|
61 | 61 |
|
| 62 | +**方法一:哈希表** |
| 63 | + |
| 64 | +我们用哈希表 `cnt1` 统计 `nums1` 中每个数出现的次数,用哈希表 `cnt2` 统计 `nums2` 中每个数出现的次数。 |
| 65 | + |
| 66 | +然后我们双重循环遍历两个哈希表,记当前 `cnt1` 遍历到的键值对为 $(a, x)$,当前 `cnt2` 遍历到的键值对为 $(b, y)$。接下来分情况讨论: |
| 67 | + |
| 68 | +- 如果 $a^2$ 能被 $b$ 整除,设 $c=\frac{a^2}{b}$,若 $b=c$,那么答案加上 $x \times y \times (y - 1)$,否则答案加上 $x \times y \times cnt2[c]$。 |
| 69 | +- 如果 $b^2$ 能被 $a$ 整除,设 $c=\frac{b^2}{a}$,若 $a=c$,那么答案加上 $x \times (x - 1) \times y$,否则答案加上 $x \times cnt1[c] \times y$。 |
| 70 | + |
| 71 | +最后将答案除以 $2$ 返回即可。 |
| 72 | + |
| 73 | +时间复杂度 $O(n \times m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为数组 `nums1` 和 `nums2` 的长度。 |
| 74 | + |
62 | 75 | <!-- tabs:start -->
|
63 | 76 |
|
64 | 77 | ### **Python3**
|
65 | 78 |
|
66 | 79 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
67 | 80 |
|
68 | 81 | ```python
|
69 |
| - |
| 82 | +class Solution: |
| 83 | + def numTriplets(self, nums1: List[int], nums2: List[int]) -> int: |
| 84 | + cnt1 = Counter(nums1) |
| 85 | + cnt2 = Counter(nums2) |
| 86 | + ans = 0 |
| 87 | + for a, x in cnt1.items(): |
| 88 | + for b, y in cnt2.items(): |
| 89 | + if a * a % b == 0: |
| 90 | + c = a * a // b |
| 91 | + if b == c: |
| 92 | + ans += x * y * (y - 1) |
| 93 | + else: |
| 94 | + ans += x * y * cnt2[c] |
| 95 | + if b * b % a == 0: |
| 96 | + c = b * b // a |
| 97 | + if a == c: |
| 98 | + ans += x * (x - 1) * y |
| 99 | + else: |
| 100 | + ans += x * y * cnt1[c] |
| 101 | + return ans >> 1 |
70 | 102 | ```
|
71 | 103 |
|
72 | 104 | ### **Java**
|
73 | 105 |
|
74 | 106 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
75 | 107 |
|
76 | 108 | ```java
|
| 109 | +class Solution { |
| 110 | + public int numTriplets(int[] nums1, int[] nums2) { |
| 111 | + Map<Integer, Integer> cnt1 = new HashMap<>(); |
| 112 | + Map<Integer, Integer> cnt2 = new HashMap<>(); |
| 113 | + for (int v : nums1) { |
| 114 | + cnt1.put(v, cnt1.getOrDefault(v, 0) + 1); |
| 115 | + } |
| 116 | + for (int v : nums2) { |
| 117 | + cnt2.put(v, cnt2.getOrDefault(v, 0) + 1); |
| 118 | + } |
| 119 | + long ans = 0; |
| 120 | + for (var e1 : cnt1.entrySet()) { |
| 121 | + long a = e1.getKey(), x = e1.getValue(); |
| 122 | + for (var e2 : cnt2.entrySet()) { |
| 123 | + long b = e2.getKey(), y = e2.getValue(); |
| 124 | + if ((a * a) % b == 0) { |
| 125 | + long c = a * a / b; |
| 126 | + if (b == c) { |
| 127 | + ans += x * y * (y - 1); |
| 128 | + } else { |
| 129 | + ans += x * y * cnt2.getOrDefault((int) c, 0); |
| 130 | + } |
| 131 | + } |
| 132 | + if ((b * b) % a == 0) { |
| 133 | + long c = b * b / a; |
| 134 | + if (a == c) { |
| 135 | + ans += x * (x - 1) * y; |
| 136 | + } else { |
| 137 | + ans += x * y * cnt1.getOrDefault((int) c, 0); |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + return (int) (ans >> 1); |
| 143 | + } |
| 144 | +} |
| 145 | +``` |
77 | 146 |
|
| 147 | +### **Go** |
| 148 | + |
| 149 | +```go |
| 150 | +func numTriplets(nums1 []int, nums2 []int) (ans int) { |
| 151 | + cnt1 := map[int]int{} |
| 152 | + cnt2 := map[int]int{} |
| 153 | + for _, v := range nums1 { |
| 154 | + cnt1[v]++ |
| 155 | + } |
| 156 | + for _, v := range nums2 { |
| 157 | + cnt2[v]++ |
| 158 | + } |
| 159 | + for a, x := range cnt1 { |
| 160 | + for b, y := range cnt2 { |
| 161 | + if a*a%b == 0 { |
| 162 | + c := a * a / b |
| 163 | + if b == c { |
| 164 | + ans += x * y * (y - 1) |
| 165 | + } else { |
| 166 | + ans += x * y * cnt2[c] |
| 167 | + } |
| 168 | + } |
| 169 | + if b*b%a == 0 { |
| 170 | + c := b * b / a |
| 171 | + if a == c { |
| 172 | + ans += x * (x - 1) * y |
| 173 | + } else { |
| 174 | + ans += x * y * cnt1[c] |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + } |
| 179 | + ans /= 2 |
| 180 | + return |
| 181 | +} |
78 | 182 | ```
|
79 | 183 |
|
80 | 184 | ### **...**
|
|
0 commit comments