Bitwise Algorithms Basics
Bitwise Algorithms Basics
The Bitwise Algorithms are used to perform operations at bit-level or to manipulate bits in different
ways. The bitwise operations are found to be much faster and are some times used to improve the
efficiency of a program.
For example: To check if a number is even or odd. This can be easily done by using Bitwise-AND(&)
operator. If the last bit of the operator is set than it is ODD otherwise it is EVEN. Therefore, if num & 1
not equals to zero than num is ODD otherwise it is EVEN.
Bitwise Operators
The operators that works at Bit level are called bitwise operators. In general there are six types of
Bitwise Operators as described below:
• & (bitwise AND) Takes two numbers as operands and does AND on every bit of two numbers.
The result of AND is 1 only if both bits are 1. Suppose A = 5 and B = 3, therefore A & B = 1.
• | (bitwise OR) Takes two numbers as operands and does OR on every bit of two numbers. The
result of OR is 1 if any of the two bits is 1. Suppose A = 5 and B = 3, therefore A | B = 7.
• ^ (bitwise XOR) Takes two numbers as operands and does XOR on every bit of two numbers.
The result of XOR is 1 if the two bits are different. Suppose A = 5 and B = 3, therefore A ^ B = 6.
• << (left shift) Takes two numbers, left shifts the bits of the first operand, the second operand
decides the number of places to shift.
• >> (right shift) Takes two numbers, right shifts the bits of the first operand, the second operand
decides the number of places to shift.
• ~ (bitwise NOT) Takes one number and inverts all bits of it. Suppose A = 5, therefore ~A = -6.
• The left shift and right shift operators cannot be used with negative numbers.
• The bitwise XOR operator is the most useful operator from technical interview perspective. We
will see some very useful applications of the XOR operator later in the course.
• The bitwise operators should not be used in place of logical operators.
• The left-shift and right-shift operators are equivalent to multiplication and division by 2
respectively.
• The & operator can be used to quickly check if a number is odd or even. The value of expression
(x & 1) would be non-zero only if x is odd, otherwise the value would be zero.
Time and Auxiliary Space used will be - O(1)
Bit Algorithms | Important Tactics
Let's look at some of the useful tactics of the Bitwise Operators which can be helpful in solving a lot of
problems really easily and quickly.
1. How to set a bit in the number 'num' : If we want to set a bit at nth position in number 'num'
,it can be done using 'OR' operator( | ).
o First we left shift '1' to n position via (1 << (n-1))
o Then, use 'OR' operator to set bit at that position.'OR' operator is used because it will set
the bit even if the bit is unset previously in binary representation of number 'num'.
3. Toggling a bit at nth position : Toggling means to turn bit 'on'(1) if it was 'off'(0) and to turn
'off'(0) if it was 'on'(1) previously.We will be using 'XOR' operator here which is this '^'. The reason
behind 'XOR' operator is because of its properties.
1) Left shift given number 1 by n-1 to create a number that has only set bit as n-th bit. temp = 1 <<
(n-1)
2) If bitwise AND of n and temp is non-zero, then result is SET else result is NOT SET.
The bitwise AND should be between number, temp. As n is the bit here, not number. Simply, if (N &
(1 << k)) > 0) its "Set".
5. Divide by 2:
x = x >> 1;
• Logic: When we do arithmetic right shift, every bit is shifted to right and blank position is
substituted with sign bit of number, 0 in case of positive and 1 in case of negative number. Since
every bit is a power of 2, with each shift we are reducing the value of each bit by factor of 2 which
is equivalent to division of x by 2.
Example:
x = 18(00010010)
x >> 1 = 9 (00001001)
6. Multiplying by 2:
x = << 1;
• Logic: When we do arithmetic left shift, every bit is shifted to left and blank position is
substituted with 0 . Since every bit is a power of 2, with each shift we are increasing the value of
each bit by a factor of 2 which is equivalent to multiplication of x by 2.
Example:
x = 18(00010010)
x << 1 = 36 (00100100)
7. Find log base 2 of a 32 bit integer:
C
int log2(int x)
{
int res = 0;
while (x >>= 1)
res++;
return res;
}
• Logic: We right shift x repeatedly until it becomes 0, meanwhile we keep count on the shift
operation. This count value is the log2(x).
8. Flipping the bits of a number: It can be done by a simple way, just simply subtract the number
from the value obtained when all the bits are equal to 1 .
For example:
Example :
Number = 23,
Binary form: 10111;
After flipping digits number will be: 01000;
Value: 11111 = 31;
9. Swapping Two Numbers: We can easily swap two numbers say a and b by using the XOR(^)
operator by applying below operations:
a ^= b;
b ^= a;
a ^= b;
Basic Problems on Bit Manipulation
Below are some problems which can be solved very easily using some of the basic concepts of Bit
Manipulation. Let's look at each of these problems and the Bitwise approach of solving them:
Problem 1: Given a number N, the task is to check whether the given number is a power of 2 or not.
Example:
Input : N = 4
Output : Yes
22 = 4
Input : N = 7
Output : No
Input : N = 32
Output : Yes
25 = 32
• Bitwise Solution: If we subtract a number which is a power of 2 with 1 then all of it's unset bits
after the only set bit become set and the set bit become unset. For example, consider 4 ( Binary
representation: 100) and 16(Binary representation: 10000), we get following after subtracting
1 from them:
3 –> 011
15 –> 01111
• You can clearly see that bitwise-AND(&) of 4 and 3 gives zero, similarly 16 and 15 also gives
zero. So, if a number N is a power of 2 then bitwise-AND(&) of N and N-1 will be zero. We can
say that N is a power of 2 or not based on the value of N&(N-1).
Problem 2: Given a number N, find the most significant set bit in the given number.
Examples:
Input : N = 10
Output : 8
Binary representation of 10 is 1010
The most significant bit corresponds
to decimal number 8.
Input : N = 18
Output : 16
• Bitwise Solution: The most-significant bit in binary representation of a number is the highest
ordered bit, that is it is the bit-position with highest value.
One of the solution is first find the bit-position corresponding to the MSB in the given number,
this can be done by calculating logarithm base 2 of the given number, i.e., log2(N) gives the
position of the MSB in N.
Once, we know the position of the MSB, calculate the value corresponding to it by raising 2 by
the power of calculated position.
That is, value = 2log2(N).
Problem 3: Given a number N, the task is to find the XOR of all numbers from 1 to N.
Examples :
Input : N = 6
Output : 7
// 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 = 7
Input : N = 7
Output : 0
// 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 = 0
• Solution:
1. Find the remainder of N by moduling it with 4.
2. If rem = 0, then xor will be same as N.
3. If rem = 1, then xor will be 1.
4. If rem = 2, then xor will be N+1.
5. If rem = 3 ,then xor will be 0.
Mark as Read
Report An IssueIf y
Check if Kth bit is set or not
Examples:
Input: n = 5, k = 1
Output: SET
Explanation: 5 is represented as 101 in binary and has its first bit set.
Input: n = 2, k = 3
Output: NOT SET
Explanation: 2 is represented as 10 in binary, all higher i.e. beyond MSB, bits are NOT SET.
Check whether the K-th bit is set or not Using Left Shift Operator:
To solve the problem follow the below idea:
• Left shift given number 1 by k-1 to create a number that has only set bit as k-th bit.
temp = 1 << (k-1)
• If bitwise AND of n and temp is non-zero, then result is SET else result is NOT SET.
Dry run of the above approach:
Input: n = 75 and k = 4
temp = 1 << (k-1) = 1 << 3 = 8
Binary Representation of temp = 0..00001000
Binary Representation of n = 0..01001011
Since bitwise AND of n and temp is non-zero, result is SET.
Below is the implementation of the above approach:
C++Java
// Java program to check if k-th bit
// of a given number is set or not
class Number {
public static void isKthBitSet(int n, int k)
{
if ((n & (1 << (k - 1))) > 0)
System.out.print("SET");
else
System.out.print("NOT SET");
}
// Driver code
public static void main(String[] args)
{
int n = 5, k = 1;
// Function call
isKthBitSet(n, k);
}
}
Output
SET
Time Complexity: O(1)
Auxiliary Space: O(1)
Check whether the K-th bit is set or not Using Right Shift
Operator:
To solve the problem follow the below idea:
If we right shift n by k-1, we get the last bit as 1 if the Kth bit is set else 0
Below is the implementation of the above approach:
C++Java
// Java program to check if
// k-th bit of a given number
// is set or not using right
// shift operator.
import java.io.*;
class GFG {
static void isKthBitSet(int n, int k)
{
if (((n >> (k - 1)) & 1) > 0)
System.out.println("SET");
else
System.out.println("NOT SET");
}
// Driver code
public static void main(String[] args)
{
int n = 5, k = 1;
// Function call
isKthBitSet(n, k);
}
}
Output
SET
Time Complexity: O(1)
Auxiliary Space: O(1)
Mark as Read
Report An IssueIf y
Count Set Bits
Write an efficient program to count the number of 1s in the binary representation of an integer.
Examples :
Input :n = 6
Output :2
Binary representation of 6 is 110 and has 2 set bits
Input :n = 13
Output :3
Binary representation of 13 is 1101 and has 3 set bit
Simple Method Loop through all bits in an integer, check if a bit is set and if it is, then increment the
set bit count. See the program below.
C++Java
// Java program to Count set
// bits in an integer
import java.io.*;
class countSetBits {
/* Function to get no of set
bits in binary representation
of positive integer n */
static int countSetBits(int n)
{
int count = 0;
while (n > 0) {
count += n & 1;
n >>= 1;
}
return count;
}
// driver program
public static void main(String args[])
{
int i = 9;
System.out.println(countSetBits(i));
}
}
Output
2
Time Complexity: O(log n)
Auxiliary Space: O(1)
1 Initialize count: = 0
2 If integer n is not zero
(a) Do bitwise & with (n-1) and assign the value back to n
n: = n&(n-1)
(b) Increment count by 1
(c) go to step 2
3 Else return count
Example for Brian Kernighan’s Algorithm:
n = 9 (1001)
count = 0
C++Java
// Java program to Count set
// bits in an integer
import java.io.*;
class countSetBits {
/* Function to get no of set
bits in binary representation
of passed binary no. */
static int countSetBits(int n)
{
int count = 0;
while (n > 0) {
n &= (n - 1);
count++;
}
return count;
}
// driver program
public static void main(String args[])
{
int i = 9;
System.out.println(countSetBits(i));
}
}
Output
2
Time Complexity: O(log n)
Auxiliary Space: O(1)
Using Lookup table: We can count bits in O(1) time using the lookup table.
Below is the implementation of the above approach:
C++Java
// Java implementation of the approach
class GFG {
// Lookup table
static int[] BitsSetTable256 = new int[256];
// Driver code
public static void main(String[] args)
{
Output
2
Time Complexity: O(1)
Auxiliary Space: O(1)
Mark as Read
Report An IssueIf y
Power of Two
Examples:
Input :n = 4
Output : Yes
Explanation: 22 = 4
Input :n = 32
Output : Yes
Explanation: 25 = 32
To solve the problem follow the below idea:
A simple method for this is to simply take the log of the number on base 2 and if you get an integer
then the number is the power of 2
Below is the implementation of the above approach:
C++Java
// Java Program to find whether a
// no is power of two
import java.lang.Math;
class GFG {
/* Function to check if x is power of 2*/
static boolean isPowerOfTwo(int n)
{
if (n == 0)
return false;
// Driver Code
public static void main(String[] args)
{
// Function call
if (isPowerOfTwo(31))
System.out.println("Yes");
else
System.out.println("No");
if (isPowerOfTwo(64))
System.out.println("Yes");
else
System.out.println("No");
}
}
Output
No
Yes
As we know that the number which will be the power of two have only one set bit , therefore when
we do bitwise AND with the number which is just less than the number which can be represented
as the power of (2) then the result will be 0 .
C++Java
// Java program of the above approach
import java.io.*;
class GFG {
// Driver code
public static void main(String[] args)
{
// Function call
if (isPowerofTwo(30)) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
if (isPowerofTwo(128)) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
}
Output
No
Yes
Time Complexity: O(1)
Auxiliary Space: O(1)
Mark as Read
Report An IssueIf y
One Odd Occurring
Given an array of positive integers. All numbers occur an even number of times except one number
which occurs an odd number of times. Find the number in O(n) time & constant space.
Examples :
C++Java
// Java program to find the element occurring
// odd number of times
class OddOccurrence {
// driver code
public static void main(String[] args)
{
int arr[] = new int[]{ 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2 };
int n = arr.length;
System.out.println(getOddOccurrence(arr, n));
}
}
Output :
5
Time Complexity: O(n^2)
Auxiliary Space: O(1)
The Best Solution is to do bitwise XOR of all the elements. XOR of all elements gives us odd occurring
elements.
C++Java
//Java program to find the element occurring odd number of times
class OddOccurance
{
int getOddOccurrence(int ar[], int ar_size)
{
int i;
int res = 0;
for (i = 0; i < ar_size; i++)
{
res = res ^ ar[i];
}
return res;
}
Output :
5
Time Complexity: O(n)
Auxiliary Space: O(1)
Mark as Read
Report An IssueIf y
Two Odd Occurring
Given an unsorted array that contains even number of occurrences for all numbers except two numbers.
Find the two numbers which have odd occurrences in O(n) time complexity and O(1) extra space.
Examples:
We can use sorting to get the odd occurring numbers in O(nLogn) time. First sort the numbers using
an O(nLogn) sorting algorithm like Merge Sort, Heap Sort.. etc. Once the array is sorted, all we need to
do is a linear scan of the array and print the odd occurring number.
We can also use hashing. Create an empty hash table which will have elements and their counts. Pick
all elements of input array one by one. Look for the picked element in hash table. If the element is found
in hash table, increment its count in table. If the element is not found, then enter it in hash table with
count as 1. After all elements are entered in hash table, scan the hash table and print elements with odd
count. This approach may take O(n) time on average, but it requires O(n) extra space.
1. The first step is to do XOR of all elements present in array. XOR of all elements gives us XOR of x and
y because of the following properties of XOR operation.
1) XOR of any number n with itself gives us 0, i.e., n ^ n = 0
2) XOR of any number n with 0 gives us n, i.e., n ^ 0 = n
3) XOR is cumulative and associative.
So we have XOR of x and y after the first step, in decimal form. E.g. 5 ^ 6 returns 3, which is computed
in bit form as 101 ^ 110 = 011. Let the ‘value’ of XOR be xor2. Every Set bit** in xor2 indicates that ‘the
corresponding bits in x and y have values different from each other’ (XOR property- ‘1 when bits are
different’).
** ( Set-bits are 1’s in binary form. E.g. 101 has 2 set bits(1’s), at 0th index and at 2nd index. )
For example, if x = 6 (0110) and y = 15 (1111), then xor2 will be (1001), the two set bits in xor2 indicate
that the corresponding bits in x and y are different, at 0th index and at 3rd index both.
2. In the second step, we pick a set bit of xor2. Idea is to use the fact that xor2 is ‘1’ in indexes where
bits of x and y are different. So we separate x and y to different groups, along with rest of the numbers
of list, based on whether the number has same set-bit or not.
We choose the rightmost set bit of xor2 as it is easy to get rightmost set bit of a number (bit magic).
If we bitwise AND a number with its negative counterpart, we get rightmost set bit. (just an observation
based property, do remember). So, (xor2) & (-xor2) will give us right set bit. Find (-number) by 2’s
complement, that is ((1’s complement) +1 ). It can also be written as (~number)+1.
7 is 00111(any no. of preceding zeroes). 1’s complement is obtained by flipping bits , 11000. Then add
1, so 2’s complement of 7 is 11001. Since first bit is 1, its a negative no.
Continuing example of 7, 7 is 00111 and -7 is 11001 , 7 & -7 is 00001. So, rightmost set bit of 7 is 1.
12 is 01100 ** and -12 is calculated by flipping digits and adding 1. So, 10011 and adding 1 gives
10100. 12 & -12, 01100 & 10100 gives 00100 as set bit, that is returned as 4 in decimal system, also
referred as Set-bit Number here.
** (since number is 32 bit, there are 28 0’s left of ‘left set-bit’, but taking only a few is okay. Positive
numbers have leftmost bit 0 and negative have 1 )
3. In third step, we separate x and y in different groups : We now know that for selected set bit index,
x and y have different corresponding bits. If we AND all numbers in list with set bit, some will give 0 and
others will give 1. We will put all numbers giving zeroes in one group and ones in another. x and y will
fall in different groups.
Step 1) XOR of all in arr will cancel all repeating nos. 10 ^12 will be ans. 1010 ^ 1100 will be 0110 that
is xor=6.
Step 2) Set bit is 10 from 0110 from visualization. (number) & (-number) is also a quick way to find
right set bit.
xor & (-xor) can be coded directly. 6 is 0110 and finding -6 by flipping digits and adding 1, 1001
+1 = 1010.
So 6 AND -6 is essentially 0110 & 1010, that is 0010 i.e. 2 – Set-bit Number.
Step 3) AND of all in list with 2 (Set bit no.) will give us numbers that give either 1 or 0, and we make
groups.
[4, 4, 12] and [2, 10, 2, 3, 3], giving 0 and 1 respectively on AND with Set-bit number.
Step 4) XOR of 1st group will give us x=12, x ^ y is known from 1st step i.e. 6. x ^(x ^y) will give us y. 12
^6 is 10.
x=12, y=10
This step works because of the same properties of XOR. All the occurrences of a number will go in
same set. XOR of all occurrences of a number which occur even number of times will result in 0 in its
set. And the xor of a set will be one of the odd occurring elements.
C++Java
// Java program to find two odd
// occurring elements
import java.util.*;
class Main
{
// main function
public static void main (String[] args)
{
int arr[] = {4, 2, 4, 5, 2, 3, 3, 1};
int arr_size = arr.length;
printTwoOdd(arr, arr_size);
}
}
Output
Naive Solution:
C++Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG {
}
public static void main (String[] args) {
oddAppearing(arr, n);
}
}
Output:
5 6
Time Complexity: O(n^2)
Auxiliary Space: O(1)
Mark as Read
Report An IssueIf y
Power Set using Bitwise
Power Set: Power set P(S) of a set S is the set of all subsets of S. For example S = {a, b, c} then P(s) = {{},
{a}, {b}, {c}, {a,b}, {a, c}, {b, c}, {a, b, c}}.
If S has n elements in it then P(s) will have 2n elements
Example:
Set = [a,b,c]
power_set_size = pow(2, 3) = 8
Run for binary counter = 000 to 111
Method 1:
For a given set[] S, the power set can be found by generating all binary numbers between 0 and 2n-1,
where n is the size of the set.
For example, for the set S {x, y, z}, generate all binary numbers from 0 to 2 -1 and for each generated
3
number, the corresponding set can be found by considering set bits in the number.
C++Java
// Java program for power set
import java .io.*;
System.out.println();
}
}
Output
a
b
ab
c
ac
bc
abc
Time Complexity: O(n2n)
Auxiliary Space: O(1)
Maximum AND Value | Explanation
Given an array arr[] of N positive elements. The task is to find the Maximum AND Value generated by
any pair of the element from the array.
Examples:
A naive approach is to iterate for all the pairs using two for loops and check for the maximum '&' value
of any pair.
Note: This approach will not fit in the given time limit since the complexity of the above method is
O(N^2).
C++Java
public static int findMaximum(int[] a, int n) {
int maxi = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
maxi = Math.max(maxi, a[i] & a[j]);
}
}
return maxi;
}
Efficient Approach: An efficient approach will be to look at this problem bitwise. Since we need to find
the maximum '&' value. The first thing that strikes our mind is that the answer should have its MSB as
far as possible. So, if two elements are considered as a pair, then their MSB should be set to as much left
as possible. Let's take an example to understand this. Consider three elements {10, 8, 2}, so to get a
maximum '&' value we need to take those elements whose MSB is as far as possible. In the given
example, we can clearly see that 10(1010) and 8(1000) have their 4th-bit from the left set and hence
will maximize the answer. Taking 2 and 10 will give our 2nd bit to be set which won't maximize our
answer.
So since the constraints permit till 10^4, hence the '&' value will also be less than that. 10^4 will range
in 2^0 to 2^14, which means we need to start our checking from the 15th bit. Initially we loop from 15
to 0 and check for the count of numbers whose that particular bit is set. Once we get the count more
than 2, the answer will have that bit set, and for the next bit from the left to be set we need to check for
both the previous all bits and the current i-th bit. The previous bits can be added to the current bit using
a '|' operator. In this way, we get all the positions of the bit which are set, which can be easily
represented as a number.
Note: We have started checking from bits 31 so that if the constraints were high, it can easily fit in.
C++Java
// Java Program to find maximum
// XOR value of a pair
import java.lang.*;
import java.util.*;
return res;
}
// driver function
public static void main(String argc[])
{
int arr[] = { 4, 8, 6, 2 };
int n = arr.length;
System.out.println("Maximum AND Value = "
+ maxAND(arr, n));
}
}
Given an array of N positive elements, the task is to find the maximum AND value generated by any pair
of elements from the array.
Examples:
C++JavaPython3C#PHPJavascript
// Java Program to find maximum
// XOR value of a pair
import java.lang.*;
import java.util.*;
return res;
}
// driver function
public static void main(String argc[])
{
int arr[] = { 4, 8, 6, 2 };
int n = arr.length;
System.out.println("Maximum AND Value = "
+ maxAND(arr, n));
}
}
Output
Maximum AND Value = 4
Time Complexity: O(N2)
Auxiliary Space: O(1)
return res;
}
// driver function
public static void main(String argc[])
{
int arr[] = { 4, 8, 6, 2 };
int n = arr.length;
System.out.println("Maximum AND Value = "
+ maxAND(arr, n));
}
}
Output
Maximum AND Value = 4
Time Complexity: O(N*log(M)) where M is the maximum element from the array and N is the size of
the array.
Auxiliary Space: O(1)