Open In App

Find bitwise AND (&) of all possible sub-arrays

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A of size N where 1\leq N \leq 10^{5}      . The task is to find the AND of all possible sub-arrays of A and then the AND of all these results.

Examples: 

Input : 1 2 3
Output : 0
All possible subarrays are 
{1}, {2}, {3}, {1, 2}, {2, 3} and {1, 2, 3}
ANDs of these subarrays are 1, 2, 3, 0, 2, 0.
AND of these ANDs is 0.

Input : 100 500 1000
Output : 96 

Approach: The Naive solution is to find the AND of all the sub-arrays and then print the AND of their results. This will lead to O(N2) solution.

Optimal Solution: Using the properties of X\&X\&...\&X=X       i:e it doesn’t matter how many times an element comes, its ANDing will be counted as one only. Thus, our problem is reduced to finding the AND of all the elements of the array only.

Implementation:

C++

// C++ program to find of all the sub-arrays
#include <bits/stdc++.h>
using namespace std;
 
// function to return AND of sub-arrays
int AND(int a[], int n)
{
    int ans = a[0];
    for (int i = 0; i < n; ++i)
        ans &= a[i]; 
    return ans;
}
 
// Driver program
int main()
{
    int a[] = { 1, 2, 3 };
 
    // size of the array
    int n = sizeof(a) / sizeof(a[0]);
 
    // print and of all subarrays
    cout << AND(a, n);
 
    return 0;
}

                    

Java

//Java program to find of all the sub-arrays
public class GFG {
 
    //function to return AND of sub-arrays
    static int AND(int a[], int n)
    {
     int ans = a[0];
     for (int i = 0; i < n; ++i)
         ans &= a[i]; 
     return ans;
    }
 
    // Driver code
    public static void main(String[] args) {
     
        int a[] = { 1, 2, 3 };
 
         // size of the array
         int n = a.length;
 
         // print and of all subarrays
         System.out.println(AND(a, n));
    }
}

                    

Python 3

# Python 3 Program  to find of all the sub-arrays
 
# function to return AND of sub-arrays
def AND(arr, n) :
 
    res = arr[0]
    for i in range(1, n):
        res &= arr[i]
        if res == 0:
            return 0
    return res
 
 
 
# Driver Code
if __name__ == "__main__" :
 
    a = [ 100, 500, 1000]
 
    # size of the array
    n = len(a)
 
    # print and of all subarrays
    print(AND(a, n))
 
# This code is contributed by ANKITRAI1

                    

C#

//C# program to find of all the sub-arrays 
 
using System;
 
public class GFG {
   
    //function to return AND of sub-arrays
    static int AND(int []a, int n)
    {
     int ans = a[0];
     for (int i = 0; i < n; ++i) 
         ans &= a[i];  
     return ans;
    }
   
    // Driver code
    public static void Main() {
       
        int []a = { 1, 2, 3 };
   
         // size of the array
         int n = a.Length;
   
         // print and of all subarrays
         Console.WriteLine(AND(a, n));
    }
}

                    

PHP

<?php
// PHP program to find of
// all the sub-arrays
 
// function to return AND
// of sub-arrays
function ANDS(&$a, $n)
{
    $ans = $a[0];
    for ($i = 0; $i < $n; ++$i)
        $ans &= $a[$i];
    return $ans;
}
 
// Driver Code
$a = array( 1, 2, 3 );
 
// size of the array
$n = sizeof($a);
 
// print and of all subarrays
echo ANDS($a, $n);
 
// This code is contributed
// by Shivi_Aggarwal
?>

                    

Javascript

<script>
//Javascript program to find of all the sub-arrays
     
    //function to return AND of sub-arrays
    function AND(a,n)
    {
        let ans = a[0];
     for (let i = 0; i < n; ++i)
         ans &= a[i]; 
     return ans;
    }
     
    // Driver code
    let a=[ 1, 2, 3 ];
    // size of the array
    let n = a.length;
    // print and of all subarrays
    document.write(AND(a, n));
     
 
 
// This code is contributed by rag2127
</script>

                    

Output
0

Time Complexity: O(N)

Auxiliary Space: O(1)

Approach: Finding AND of all subarrays using bit manipulation and hashing.

We can use the bitwise AND operator to get the AND of all sub-arrays. The idea is to count the number of times each bit is set in the sub-arrays. If a bit is set in all the sub-arrays, then it will be set in the result. We can use a hash table to count the number of times each bit is set. Then, we can check if the bit is set in all the sub-arrays or not.

Algorithm:

  • Initialize a hash table to count the number of times each bit is set.
  • Traverse the array and for each element, traverse all the bits and if the bit is set, increment the count of that bit in the hash table.
  • Initialize the result variable to 0.
  • Traverse the hash table and for each bit, if the count is equal to the length of the array, set the bit in the result variable.
  • Return the result variable.

Here is the implementation of above algorithm:-

C++

#include <iostream>
#include <unordered_map>
using namespace std;
 
int AND(int arr[], int n) {
    unordered_map<int, int> bit_count;
    for (int i = 0; i < n; i++) {
        int num = arr[i];
        int pos = 0;
        while (num > 0) {
            if (num & 1) {
                if (bit_count.find(pos) == bit_count.end()) {
                    bit_count[pos] = 1;
                } else {
                    bit_count[pos]++;
                }
            }
            num >>= 1;
            pos++;
        }
    }
    int res = 0;
    for (auto it : bit_count) {
        if (it.second == n) {
            res |= (1 << it.first);
        }
    }
    return res;
}
 
int main() {
    int arr[] = {1, 2, 3};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << AND(arr, n) << endl;
    return 0;
}

                    

Java

import java.util.HashMap;
import java.util.Map;
 
public class Main {
    static int AND(int[] arr) {
        int n = arr.length;
        Map<Integer, Integer> bit_count = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int num = arr[i];
            int pos = 0;
            while (num > 0) {
                if ((num & 1) == 1) {
                    if (!bit_count.containsKey(pos)) {
                        bit_count.put(pos, 1);
                    } else {
                        bit_count.put(pos, bit_count.get(pos) + 1);
                    }
                }
                num >>= 1;
                pos++;
            }
        }
        int res = 0;
        for (Map.Entry<Integer, Integer> entry : bit_count.entrySet()) {
            if (entry.getValue() == n) {
                res |= (1 << entry.getKey());
            }
        }
        return res;
    }
 
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(AND(arr));
    }
}

                    

Python

def AND(arr):
    n = len(arr)
    bit_count = {}
    for i in range(n):
        num = arr[i]
        pos = 0
        while num > 0:
            if num & 1:
                if pos not in bit_count:
                    bit_count[pos] = 1
                else:
                    bit_count[pos] += 1
            num >>= 1
            pos += 1
    res = 0
    for bit, count in bit_count.items():
        if count == n:
            res |= (1 << bit)
    return res
 
arr = [1, 2, 3]
print(AND(arr))

                    

C#

using System;
using System.Collections.Generic;
 
public class Program {
    static int AND(int[] arr) {
        int n = arr.Length;
        Dictionary<int, int> bit_count = new Dictionary<int, int>();
        for (int i = 0; i < n; i++) {
            int num = arr[i];
            int pos = 0;
            while (num > 0) {
                if ((num & 1) == 1) {
                    if (!bit_count.ContainsKey(pos)) {
                        bit_count.Add(pos, 1);
                    } else {
                        bit_count[pos]++;
                    }
                }
                num >>= 1;
                pos++;
            }
        }
        int res = 0;
        foreach (KeyValuePair<int, int> pair in bit_count) {
            if (pair.Value == n) {
                res |= (1 << pair.Key);
            }
        }
        return res;
    }
 
    static void Main(string[] args) {
        int[] arr1 = new int[] { 1, 2, 3 };
        Console.WriteLine(AND(arr1));
 
        int[] arr2 = new int[] { 100, 500, 1000 };
        Console.WriteLine(AND(arr2));
    }
}

                    

Javascript

function AND(arr) {
    const n = arr.length;
    const bit_count = new Map();
    for (let i = 0; i < n; i++) {
        let num = arr[i];
        let pos = 0;
        while (num > 0) {
            if (num & 1) {
                if (!bit_count.has(pos)) {
                    bit_count.set(pos, 1);
                } else {
                    bit_count.set(pos, bit_count.get(pos) + 1);
                }
            }
            num >>= 1;
            pos++;
        }
    }
    let res = 0;
    for (let [bit, count] of bit_count) {
        if (count === n) {
            res |= (1 << bit);
        }
    }
    return res;
}
 
const arr1 = [1, 2, 3];
console.log(AND(arr1)); // expected output: 0
 
const arr2 = [100, 500, 1000];
console.log(AND(arr2)); // expected output: 96

                    

Output
0

The Time complexity of this approach is O(N * L), where N is the length of the input array and L is the maximum number of bits required to represent any number in the array.

The Space complexity of this approach is also O(L), as we are using a dictionary to store the count of set bits for each position.



Last Updated : 30 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads