计算具有给定XOR

时间:2018-09-09 16:49:05

标签: python xor

给出一个大小为N的列表。找出对数(i,j),使得A [i] XOR A [j] = x,并且1 <= i

输入:列表= [3、6、8、10、15、50],x = 5

输出:2

说明:(3 ^ 6)= 5和(10 ^ 15)= 5

这是我的代码(蛮力):

import itertools
n=int(input())
pairs=0
l=list(map(int,raw_input().split()))
q=[x for x in l if x%2==0]
p=[y for y in l if y%2!=0]
for a, b in itertools.combinations(q, 2):
    if (a^b!=2) and ((a^b)%2==0) and (a!=b):
        pairs+=1
for a, b in itertools.combinations(p, 2):
    if (a^b!=2) and ((a^b)%2==0) and (a!=b):
        pairs+=1
print pairs

如何在python中复杂度为O(n)的情况下更有效地做到这一点?

2 个答案:

答案 0 :(得分:0)

观察到如果为A[i]^A[j] == x,则表示A[i]^x == A[j]A[j]^x == A[i]

因此,O(n)解决方案将遍历关联映射(dict),其中每个键都是A中的一项,而每个值都是该项的相应计数。然后,对于每个项目,计算A[i]^x,然后查看A[i]^x是否在地图中。如果它在地图中,则表示A[i]^A[j] == x代表 some j。由于我们有一个映射,其中所有项的计数等于A[j],因此对的总数为num_Ai * num_Aj。请注意,由于XOR是可交换的(即A[i]^A[j] == A[j]^A[i]),因此每个元素将被计数两次,因此,由于我们已对每个对进行了两次计数,因此必须将最终计数除以2。

def create_count_map(lst):
    result = {}
    for item in lst:
        if item in result:
            result[item] += 1
        else:
            result[item] = 1
    return result

def get_count(lst, x):
    count_map = create_count_map(lst)
    total_pairs = 0
    for item in count_map:
        xor_res = item ^ x
        if xor_res in count_map:
            total_pairs += count_map[xor_res] * count_map[item]
    return total_pairs // 2

print(get_count([3, 6, 8, 10, 15, 50], 5))
print(get_count([1, 3, 1, 3, 1], 2))

输出

2
6

根据需要。

为什么这个O(n)?

list转换为dict。字典包含列表中每个项目的计数为O(n)时间。

计算item ^ x的时间为O(1),计算此结果是否在dict中的时间也为O(1)。 dict键访问也是O(1),两个元素的乘法也是如此。我们要进行所有这n次操作,因此循环需要O(n)时间。

O(n)+ O(n)减少为O(n)时间。

经过编辑可正确处理重复项。

答案 1 :(得分:0)

对于X = 0,可接受的答案没有给出正确的结果。此代码处理该微小错误。您也可以修改它以获取其他值的答案。

def calculate(a) :

# Finding the maximum of the array
maximum = max(a)

# Creating frequency array
# With initial value 0
frequency = [0 for x in range(maximum + 1)]

# Traversing through the array 
for i in a :

    # Counting frequency
    frequency[i] += 1

answer = 0

# Traversing through the frequency array
for i in frequency :

    # Calculating answer
    answer = answer + i * (i - 1) // 2

return answer