Maximum AND value of a pair in an array

Last Updated : 30 Jun, 2026

Given an array arr[] of positive integers, return the maximum bitwise AND value obtained by any pair (arr[i], arr[j]) such that i ≠ j.

Examples: 

Input: arr[] = [4, 8, 12, 16]
Output: 8
Explanation: Pair (8,12) has the maximum AND value 8.

Input: arr[] = [4, 8, 16, 2]
Output: 0
Explanation: All pairwise AND values are 0, so the maximum possible AND value among them is also 0.

Try It Yourself
redirect icon

[Naive Approach] Brute Force - O(n^2) Time and O(1) Space

The idea is to iterate over all the possible pairs using two nested loops and calculate the bitwise AND for each pair and maintain a variable to track and return the maximum value found during these iterations.

C++
#include <iostream>
#include <vector>
using namespace std;

int maxAND(vector<int>& arr)
{
    int n = arr.size();
    
    int res = 0;
    
    // Iterate through all unique pairs (i, j)
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            res = max(res, arr[i] & arr[j]);

    return res;
}

int main()
{
    vector<int> arr = { 4, 8, 6, 2 }; 
    cout << maxAND(arr);
    return 0;
}
Java
import java.lang.*;
import java.util.*;

public class GFG {
    static int maxAND(int arr[])
    {
        int n = arr.length;
        int res = 0;
        
        // Iterate through all unique pairs (i, j)
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++)
                res = res > (arr[i] & arr[j])
                          ? res
                          : (arr[i] & arr[j]);

        return res;
    }

    public static void main(String argc[])
    {
        int arr[] = { 4, 8, 6, 2 }; 
        System.out.println(maxAND(arr));
    }
}
Python
def maxAND(arr):
    n = len(arr)   
    res = 0

    # Iterate through all unique pairs (i, j)
    for i in range(0, n):
        for j in range(i + 1, n):
            res = max(res, arr[i] & arr[j])

    return res

if __name__ == "__main__":
    arr = [4, 8, 6, 2] 
    print(maxAND(arr)) 
C#
using System;

public class GFG {
    public static int maxAND(int[] arr)
    {
        int n = arr.Length; 
        int res = 0;
        
        // Iterate through all unique pairs (i, j)
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++)
                res = res > (arr[i] & arr[j])
                          ? res
                          : (arr[i] & arr[j]);

        return res;
    }

    public static void Main()
    {
        int[] arr = { 4, 8, 6, 2 };
        int n = arr.Length;
        Console.WriteLine(maxAND(arr));
    }
}
 
JavaScript
function maxAND(arr)
{
    var res = 0;
    var n = arr.length;
    
    // Iterate through all unique pairs (i, j)
    for (var i=0; i<n; i++)
       for (var j=i+1; j<n; j++)
          res = Math.max(res, arr[i] & arr[j]);

    return res;
}

// Driver code
var arr = [4, 8, 6, 2];
console.log(maxAND(arr));

Output
4

[Expected Approach] Bit Manipulation - O(n log(max_element)) Time and O(1) Space

The idea is based on the property of AND operator. AND operation of any two bits results in 1 if both bits are 1. We start from the MSB and check whether we have a minimum of two elements of array having set value. If yes then that MSB will be part of our solution and be added to result otherwise we will discard that bit. Similarly, iterating from MSB to LSB (32 to 1) for bit position we can easily check which bit will be part of our solution and will keep adding all such bits to our solution. 

Let's understand with an example:
Given arr[] = [4, 8, 12, 16]
Bit-representation of each element : 4 = 100, 8 = 1000, 12 = 1100, 16 = 10000 

  • Check Bit 4 (Value 16): If we can make res = 16 (10000). Numbers with Bit 4 set: Only 16. Count: 1. Since we need a pair (at least 2), this fails. res stays 0.
  • Check Bit 3 (Value 8): If we can make res = 8 (01000). Numbers with Bit 3 set: 8 and 12. Count: 2. Success! We have a pair. We permanently keep this bit. res becomes 8.
  • Check Bit 2 (Value 4): If we can add this bit to our existing result to make res = 12 (01100). Numbers with both Bit 3 and Bit 2 set: Only 12. Count: 1. Fails. res stays 8.
  • Check Bit 1 (Value 2) & Bit 0 (Value 1): Checking res = 10 (01010) and res = 9 (01001) will yield a count of 0, as no numbers in our array have those specific bit combinations. res stays 8.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to check number of elements
// having set msb as of pattern
int checkBit(int pattern, vector<int>& arr)
{
    int n = arr.size();
    int count = 0;
    for (int i = 0; i < n; i++)
        if ((pattern & arr[i]) == pattern)
            count++;
    return count;
}

int maxAND(vector<int>& arr)
{
    int  n = arr.size();
    int res = 0, count;

    // iterate over total of 32bits from msb to lsb
    for (int bit = 18; bit >= 0; bit--)
    {

        // find the count of element having same pattern as
        // obtained by adding bits on every iteration.
        count = checkBit(res | (1 << bit), arr);

        // if count >= 2 set particular bit in result
        if (count >= 2)
            res = res | (1 << bit);
    }

    return res;
}

int main()
{
    vector<int> arr = {4, 8, 6, 2}; 
    cout << maxAND(arr);
    return 0;
}
Java
import java.lang.*;
import java.util.*;

public class GFG {

    // Function to check number of elements
    // having set msb as of pattern
    static int checkBit(int pattern, int arr[])
    {
        int n = arr.length;
        int count = 0;
        for (int i = 0; i < n; i++)
            if ((pattern & arr[i]) == pattern)
                count++;
        return count;
    }

    static int maxAND(int arr[])
    {
        int n = arr.length;
        int res = 0, count;

        // iterate over total of 32bits
        // from msb to lsb
        for (int bit = 18; bit >= 0; bit--) {
            
            // find the count of element
            // having set msb
            count = checkBit(res | (1 << bit), arr);

            // if count >= 2 set particular
            // bit in result
            if (count >= 2)
                res |= (1 << bit);
        }

        return res;
    }

    public static void main(String argc[])
    {
        int arr[] = { 4, 8, 6, 2 };
        
        System.out.println(maxAND(arr));
    }
} 
Python
# Function to check number of
# elements having set msb as of pattern 
def checkBit(pattern, arr):
    count = 0
    n = len(arr)
    for i in range(0, n):
        if ((pattern & arr[i]) == pattern):
            count = count + 1
    return count

def maxAND(arr):
    res = 0
    n = len(arr)
    
    # iterate over total of 32bits
    # from msb to lsb
    for bit in range(18, -1, -1):

        # find the count of element
        # having set  msb
        count = checkBit(res | (1 << bit), arr)

        # if count >= 2 set particular
        # bit in result
        if (count >= 2):
            res = res | (1 << bit)

    return res

if __name__ == "__main__":
    arr = [4, 8, 6, 2]
    n = len(arr)
    print(maxAND(arr)) 
C#
using System;

public class GFG {

    // Function to check
    // number of elements having
    // set msb as of pattern
    static int checkBit(int pattern, int[] arr)
    {
        int n = arr.Length;
        int count = 0;
        for (int i = 0; i < n; i++)
            if ((pattern & arr[i]) == pattern)
                count++;
        return count;
    }

    static int maxAND(int[] arr)
    {
        int n = arr.Length;
        int res = 0, count;
            
        // iterate over total of 32bits
        // from msb to lsb
        for (int bit = 18; bit >= 0; bit--) {

            // find the count of element
            // having set msb
            count = checkBit(res | (1 << bit), arr);

            // if count >= 2 set particular
            // bit in result
            if (count >= 2)
                res |= (1 << bit);
        }

        return res;
    }

    public static void Main()
    {
        int[] arr = { 4, 8, 6, 2 };
        
        Console.WriteLine(maxAND(arr));
    }
}
 
JavaScript
// Function to check
// number of elements having
// set msb as of pattern
function checkBit(pattern, arr)
{
    let n = arr.length;
    let count = 0;
    for (let i = 0; i < n; i++)
        if ((pattern & arr[i]) == pattern)
            count++;
    return count;
}

function maxAND (arr)
{
    let n = arr.length;
    let res = 0, count;

    // iterate over total of 32bits
    // from msb to lsb
    for (let bit = 18; bit >= 0; bit--)
    {

        // find the count of element
        // having set msb
        count = checkBit(res | (1 << bit), arr);

        // if count >= 2 set particular
        // bit in result
        if (count >= 2)    
            res |= (1 << bit);    
    }

    return res;
}

// Driver code
let arr = [4, 8, 6, 2];
console.log(maxAND(arr));
 

Output
4
Comment