在集合中查找“AND”的最大值

时间:2017-03-22 17:24:06

标签: python

  

给定数字(x)和阈值,找到对所有数字执行Binary AND直到x可以达到的最大值。最大值应小于阈值。

例如:如果输入2,3,那么

A = 1 ; B = 1 ; A & B = 1
A = 1 ; B = 2 ; A & B = 0
A = 2 ; B = 1 ; A & B = 0
A = 2 ; B = 2 ; A & B = 2

在这个例子中,我从AND操作得到的最大值是2,它小于阈值3所以2是应该打印的答案。

我必须从所有这些可能的输入中找到最大值,然后打印它们。我用这段代码解决了这个问题

maxValue = 0
n,k1 = input().strip().split(' ')
n,k1 = [int(n),int(k1)]
for j in range (1,n):
    for k in range (j+1,n):
        jkValue = j&k
        if jkValue > maxValue and jkValue < k1:
            maxValue = jkValue
print(maxValue)

根据我之前对此类问题的经验,如果我使用某种数据结构,例如listmap,我可以更有效地解决这个问题。

是否可以使用数据结构解决此问题或者我是否达到了最低复杂度?如果可以做得更好那么?

1 个答案:

答案 0 :(得分:0)

我认为问题在于找到0<i<j<n最大化i&j i&j<k。{/ p>

您可以通过逐位构造结果找到答案。从高位开始,您可以确定是否有两个数字的最高位已经由前面的步骤确定,并且两者都设置了当前位,这样它们都在范围内,并且它们的位数和小于{{1} }。

这在O(log k)时间运行(或者更准确地说,它执行O(log k)算术运算)。

k

这是一个简单且明显正确的解决方案,在O(n ^ 2)时间运行,有些测试表明高效版本为小n和k产生相同的结果。

# max_and returns the max i&j subject to:
# 0 < i < j < n and i&j < k.
def max_and(n, k):
    r = 0
    b = 1
    while b < k:
        b <<= 1
    while b:
        # Can we set bit b in the result?
        # We can't if r|b >= k.
        # Otherwise, are there two numbers greater than or equal to r,
        # and less than n, both with bit b set?
        # The two smallest numbers greater than or equal to r with
        # bit b set are r|b and ((r|b) + 1) | (r|b). We need only
        # test the latter against n.
        if (r | b) | ((r | b) + 1) < n and r|b < k:
            r |= b
        b >>= 1
    return r