HackerRank bitwiseAnd challenge - algorithm is too slow?
Your algorithm has a brute force approach, but it can be done more efficiently.
First, observe some properties of this problem:
- 𝐴 & 𝐵 will never be greater than 𝐴 nor than 𝐵
- If we think we have a solution 𝐶, then both 𝐴 and 𝐵 should have the same 1-bits as 𝐶 has, including possibly a few more.
- We want 𝐴 and 𝐵 to not be greater than needed, since they need to be not greater than 𝑁, so given the previous point, we should let 𝐴 be equal to 𝐶, and let 𝐵 just have one 1-bit more than 𝐴 (since it should be a different number).
- The least possible value for 𝐵 is then to set a 1-bit at the least bit in 𝐴 that is still 0.
- If this 𝐵 is still not greater than 𝑁, then we can conclude that 𝐶 is a solution.
- With the above steps in mind, it makes sense to first try with the greatest 𝐶 possible, i.e. 𝐶=𝐾−1, and then reduce 𝐶 until the above routine finds a 𝐵 that is not greater than 𝑁.
Here is the code for that:
def bitwiseAnd(N, K):
for A in range(K - 1, 0, -1):
# Find the least bit that has a zero in this number A:
# Use some "magic" to get the number with just one 1-bit in that position
bit = (A + 1) & -(A + 1)
B = A + bit
if B <= N:
# We know that A & B == B here, so just return A
return A
return 0