遍历去重后的 nums,统计 c(\textit{nums}[i]) 的个数,记录在 cnt 中,然后写一个二重循环遍历 cnt,对于所有的 c(x)+c(y)\ge k,累加 cnt}[c(x)]\cdot\textit{cnt}[c(y)],表示从这两组中各选一个 x 和 y 组成优质数对的个数(乘法原理)。
复杂度分析
时间复杂度:O(n+U^2),其中 n 为 nums 的长度,U 为不同的 c(\textit{nums}[i]) 的个数,不超过 30。
空间复杂度:O(n+U)。
[sol1-Python3]
1 2 3 4 5 6 7 8 9
classSolution: defcountExcellentPairs(self, nums: List[int], k: int) -> int: cnt = Counter(x.bit_count() for x inset(nums)) ans = 0 for cx, ccx in cnt.items(): for cy, ccy in cnt.items(): if cx + cy >= k: # (x,y) 是优质数对 ans += ccx * ccy return ans
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { publiclongcountExcellentPairs(int[] nums, int k) { varvis=newHashSet<Integer>(); varcnt=newHashMap<Integer, Integer>(); for (var x : nums) if (vis.add(x)) { varc= Integer.bitCount(x); cnt.put(c, cnt.getOrDefault(c, 0) + 1); } varans=0L; for (var x : cnt.entrySet()) for (var y : cnt.entrySet()) if (x.getKey() + y.getKey() >= k) ans += (long) x.getValue() * y.getValue(); return ans; } }
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: longlongcountExcellentPairs(vector<int> &nums, int k){ unordered_map<int, int> cnt; for (int x : unordered_set<int>(nums.begin(), nums.end())) // 去重 ++cnt[__builtin_popcount(x)]; long ans = 0L; for (auto &[cx, ccx] : cnt) for (auto &[cy, ccy] : cnt) if (cx + cy >= k) // (x,y) 是优质数对 ans += (long) ccx * ccy; return ans; } };
[sol1-Go]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
funccountExcellentPairs(nums []int, k int) (ans int64) { vis := map[int]bool{} cnt := map[int]int{} for _, x := range nums { if !vis[x] { vis[x] = true cnt[bits.OnesCount(uint(x))]++ } } for cx, ccx := range cnt { for cy, ccy := range cnt { if cx+cy >= k { // (x,y) 是优质数对 ans += int64(ccx) * int64(ccy) } } } return }
publiclongcountExcellentPairs(int[] nums, int k) { varvis=newHashSet<Integer>(); varcnt=newint[U]; for (var x : nums) if (vis.add(x)) ++cnt[Integer.bitCount(x)]; varans=0L; vars=0; for (vari= k; i < U; ++i) s += cnt[i]; for (varcx=0; cx < U; ++cx) { ans += (long) cnt[cx] * s; varcy= k - 1 - cx; if (0 <= cy && cy < U) s += cnt[cy]; } return ans; } }
[sol2-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { staticconstexprint U = 30; public: longlongcountExcellentPairs(vector<int> &nums, int k){ int cnt[U] = {}; for (int x : unordered_set<int>(nums.begin(), nums.end())) // 去重 ++cnt[__builtin_popcount(x)]; long ans = 0L; int s = 0; for (int i = k; i < U; ++i) s += cnt[i]; for (int cx = 0; cx < U; ++cx) { ans += (long) cnt[cx] * s; int cy = k - 1 - cx; if (0 <= cy && cy < U) s += cnt[cy]; } return ans; } };
funccountExcellentPairs(nums []int, k int) (ans int64) { const U = 30 vis := map[int]bool{} cnt := [U]int{} for _, x := range nums { if !vis[x] { vis[x] = true cnt[bits.OnesCount(uint(x))]++ } } s := 0 for i := k; i < U; i++ { s += cnt[i] } for cx, ccx := range cnt { ans += int64(ccx) * int64(s) cy := k - 1 - cx if0 <= cy && cy < U { s += cnt[cy] } } return }