📅  最后修改于: 2023-12-03 15:35:55.417000             🧑  作者: Mango
这里介绍一种计算不能形成任何对的元素总数为2的幂的元素的计数的方法,假设给定一个长度为N的非空整数数组arr[]
。
首先,一对元素(a[i], a[j])
可以形成2的幂的总数,当且仅当a[i] ^ a[j]
为2的幂。
假设所有的元素都可以形成若干个这样的对。我们把这些元素分成两类:
类别A:a[i]
为2的幂,a[j]
为非2的幂。
类别B:a[i]
为非2的幂,a[j]
为2的幂。
对于类别A,如果除去a[i]
后剩下的元素个数为M,而M又都为2的幂,那么a[i]
也不能形成任何对。因为无论如何组合,都只能得到(a[i], a[i]), (a[i], a[k])
这两种情况(k为除去a[i]后的剩余元素),不能构成2的幂数量。
同样的,对于类别B,如果除去a[j]
后剩下的元素个数为M,而M又都为2的幂,那么a[j]
也不能形成任何对。
考虑到一个元素只有可能被算一次,我们可以用哈希表来记录每个元素的出现次数,这样只需要遍历数组两次,就可以得到所有的不能形成任何对的元素的总数。
下面是Python实现的代码,其中get_pow2_count()
函数返回不能形成任何对的元素总数,count_pow2_pairs()
函数返回所有能够形成2的幂数量的元素对。
from collections import defaultdict
def count_pow2_pairs(arr):
n = len(arr)
count = 0
cnts = defaultdict(int)
for i in range(n):
cnts[arr[i]] += 1
for i in range(n - 1):
for j in range(i + 1, n):
if (arr[i] ^ arr[j]) & (arr[i] ^ arr[j] - 1) == 0:
count += 1
return count
def get_pow2_count(arr):
cnts = defaultdict(int)
pow2s = set([2 ** i for i in range(31)])
for a in arr:
cnts[a] += 1
for a in arr:
if cnts[a] > 1:
continue
if a in pow2s:
continue
if (a & a - 1) == 0 and cnts.get(0, 0) < 2:
continue
if (a & a - 1) != 0 and cnts.get(a ^ a - 1, 0) > 0:
continue
return 1
return 0
以上算法的时间复杂度为$O(n^2)$。对于较大的数组会有性能问题,但对于现代计算机和一般的数组长度,可以接受。