Skip to content
Related Articles

Related Articles

Check if an array can be split into K non-overlapping subarrays whose Bitwise AND values are equal
  • Last Updated : 26 Jan, 2021

Given an array arr[] of size N and a positive integer K, the task is to check if the array can be split into K non-overlapping and non-empty subarrays such that Bitwise AND of all the subarrays are equal. If found to be true, then print “YES”. Otherwise, print “NO”.

Examples:

Input: arr[] = { 3, 2, 2, 6, 2 }, K = 3 
Output: YES 
Explanation: 
Splitting the array into K( = 3) subarrays as { { 3, 2 }, { 2, 6 }, { 2 } } 
Therefore, the required output is YES.

Input: arr[] = { 4, 3, 5, 2 }, K = 3 
Output: NO

Naive Approach: The simplest approach to solve this problem is to split the array into K subarrays in all possible ways and in every possible way, check if Bitwise AND of all K subarrays are equal or not. If found to be true for any split, then print “YES”. Otherwise, print “NO”



Time Complexity: O(N3)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to use the fact that if ith bit of at least one element of the subarray is 0, then ith bit of bitwise AND of that subarray is also 0. Follow the steps below to solve the problem:

  • Initialize a variable, say flag, to check if the array can be spit into K subarrays such that Bitwise AND of all the subarrays are equal.
  • Initialize a 2D array, say pref[][], where pref[i][j] stores the count of contiguous array elements up to ith index whose jth bit is set.
  • Iterate over the range [0, N – K]. For every jth bit of ith element, check for the following conditions: 
    • If jth bit of all the array elements up to ith index are set and jth bit of at least one element of the array after ith index are not set, then update flag = false.
    • If jth bit of at least one array elements up to ith index are not set and jth bit of all the array elements after the ith index are set then update flag = false
  • Finally, check if flag equal to true or not. If found to be true, then print “YES”.
  • Otherwise, print “NO”.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Utility function to check if the array
// can be split into K subarrays whose
// bitwise AND are equal
bool equalPartitionUtil(int arr[], int N, int K)
{
 
    // pref[i][j]: Stores count of contigious
    // array elements upto i-th index whose
    // j-th bit is set
    int pref[N][32];
 
    // Initialize pref[][] array
    memset(pref, 0, sizeof(pref));
 
    // Fill the prefix array
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < 32; j++) {
            if (i) {
 
                // Check if j-th bit set or not
                int X = ((arr[i] & (1 << j)) > 0);
 
                // Update pref[i][j]
                pref[i][j] = pref[i - 1][j] + X;
            }
 
            else {
 
                // Update pref[i][j]
                pref[i][j] = ((arr[i] & (1 << j)) > 0);
            }
        }
    }
 
    // Iterate over the range[0, N - K]
    for (int i = 0; i < N - K + 1; i++) {
        bool flag = true;
 
        for (int j = 0; j < 32; j++) {
 
            // Get count of elements that have
            // jth bit set
            int cnt = pref[i][j];
 
            // Check if first case is satisfied
            if (cnt == i + 1
                && pref[N - 1][j] - pref[i][j] != N - i - 1)
                flag = false;
 
            // Check if second case is satisfied
            if (cnt != i + 1
                && N - i - 1 - (pref[N - 1][j] - pref[i][j]) < K - 1)
                flag = false;
        }
 
        if (flag)
            return true;
    }
 
    return false;
}
 
// Fucntion to check if the array
// can be split into K subarrays
// having equal value of bitwise AND
void equalPartition(int arr[], int N, int K)
{
    if (equalPartitionUtil(arr, N, K))
        cout << "YES";
    else
        cout << "NO";
}
 
// Driver code
int main()
{
    // Given array
    int arr[] = { 3, 2, 2, 6, 2 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 3;
 
    // Function Call
    equalPartition(arr, N, K);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Utility function to check if the array
// can be split into K subarrays whose
// bitwise AND are equal
static boolean equalPartitionUtil(int arr[],
                                  int N, int K)
{
     
    // pref[i][j]: Stores count of contigious
    // array elements upto i-th index whose
    // j-th bit is set
    int [][]pref = new int[N][32];
 
    // Fill the prefix array
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < 32; j++)
        {
            if (i > 0)
            {
                 
                // Check if j-th bit set or not
                int X = ((arr[i] & (1 << j)) > 0) ? 1 : 0;
 
                // Update pref[i][j]
                pref[i][j] = pref[i - 1][j] + X;
            }
 
            else
            {
                 
                // Update pref[i][j]
                pref[i][j] = ((arr[i] & (1 << j)) > 0) ? 1 : 0;
            }
        }
    }
 
    // Iterate over the range[0, N - K]
    for(int i = 0; i < N - K + 1; i++)
    {
        boolean flag = true;
 
        for(int j = 0; j < 32; j++)
        {
             
            // Get count of elements that have
            // jth bit set
            int cnt = pref[i][j];
 
            // Check if first case is satisfied
            if (cnt == i + 1 && pref[N - 1][j] -
                   pref[i][j] != N - i - 1)
                flag = false;
 
            // Check if second case is satisfied
            if (cnt != i + 1 && N - i - 1 - (
                pref[N - 1][j] - pref[i][j]) < K - 1)
                flag = false;
        }
        if (flag)
            return true;
    }
    return false;
}
 
// Fucntion to check if the array
// can be split into K subarrays
// having equal value of bitwise AND
static void equalPartition(int arr[], int N, int K)
{
    if (equalPartitionUtil(arr, N, K))
        System.out.print("YES");
    else
        System.out.print("NO");
}
 
// Driver code
public static void main(String[] args)
{
     
    // Given array
    int arr[] = { 3, 2, 2, 6, 2 };
 
    // Size of the array
    int N = arr.length;
 
    // Given K
    int K = 3;
 
    // Function Call
    equalPartition(arr, N, K);
}
}
 
// This code is contributed by shikhasingrajput

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
 
# Utility function to check if the array
# can be split into K subarrays whose
# bitwise AND are equal
def equalPartitionUtil(arr, N, K):
 
    # pref[i][j]: Stores count of contigious
    # array elements upto i-th index whose
    # j-th bit is set
    pref = [[0 for x in range(32)]for y in range(N)]
 
    # Fill the prefix array
    for i in range(N):
        for j in range(32):
            if (i):
 
                # Check if j-th bit set or not
                X = ((arr[i] & (1 << j)) > 0)
 
                # Update pref[i][j]
                pref[i][j] = pref[i - 1][j] + X
 
            else:
 
                # Update pref[i][j]
                pref[i][j] = ((arr[i] & (1 << j)) > 0)
 
    # Iterate over the range[0, N - K]
    for i in range(N - K + 1):
        flag = True
        for j in range(32):
 
            # Get count of elements that have
            # jth bit set
            cnt = pref[i][j]
 
            # Check if first case is satisfied
            if (cnt == i + 1
                    and pref[N - 1][j] - pref[i][j] != N - i - 1):
                flag = False
 
            # Check if second case is satisfied
            if (cnt != i + 1
                    and N - i - 1 - (pref[N - 1][j] - pref[i][j]) < K - 1):
                flag = False
        if (flag):
            return True
    return False
 
# Fucntion to check if the array
# can be split into K subarrays
# having equal value of bitwise AND
def equalPartition(arr, N, K):
    if (equalPartitionUtil(arr, N, K)):
        print("YES")
    else:
        print("NO")
 
# Driver code
if __name__ == "__main__":
 
    # Given array
    arr = [3, 2, 2, 6, 2]
 
    # Size of the array
    N = len(arr)
 
    # Given K
    K = 3
 
    # Function Call
    equalPartition(arr, N, K)
 
    # This code is contributed by chitranayal.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Utility function to check if the array
// can be split into K subarrays whose
// bitwise AND are equal
static bool equalPartitionUtil(int []arr,
                               int N, int K)
{
     
    // pref[i,j]: Stores count of contigious
    // array elements upto i-th index whose
    // j-th bit is set
    int [,]pref = new int[N, 32];
     
    // Fill the prefix array
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < 32; j++)
        {
            if (i > 0)
            {
                 
                // Check if j-th bit set or not
                int X = ((arr[i] & (1 << j)) > 0) ? 1 : 0;
 
                // Update pref[i,j]
                pref[i, j] = pref[i - 1, j] + X;
            }
 
            else
            {
                 
                // Update pref[i,j]
                pref[i, j] = ((arr[i] & (1 << j)) > 0) ? 1 : 0;
            }
        }
    }
 
    // Iterate over the range[0, N - K]
    for(int i = 0; i < N - K + 1; i++)
    {
        bool flag = true;
 
        for(int j = 0; j < 32; j++)
        {
             
            // Get count of elements that have
            // jth bit set
            int cnt = pref[i, j];
 
            // Check if first case is satisfied
            if (cnt == i + 1 && pref[N - 1, j] -
                pref[i, j] != N - i - 1)
                flag = false;
 
            // Check if second case is satisfied
            if (cnt != i + 1 && N - i - 1 - (
                pref[N - 1, j] - pref[i, j]) < K - 1)
                flag = false;
        }
        if (flag)
            return true;
    }
    return false;
}
 
// Fucntion to check if the array
// can be split into K subarrays
// having equal value of bitwise AND
static void equalPartition(int []arr, int N, int K)
{
    if (equalPartitionUtil(arr, N, K))
        Console.Write("YES");
    else
        Console.Write("NO");
}
 
// Driver code
public static void Main(String[] args)
{
     
    // Given array
    int []arr = { 3, 2, 2, 6, 2 };
 
    // Size of the array
    int N = arr.Length;
 
    // Given K
    int K = 3;
 
    // Function Call
    equalPartition(arr, N, K);
}
}
 
// This code is contributed by shikhasingrajput

chevron_right


Output: 

YES

 

Time Complexity: O(32 * N)
Auxiliary Space: O(32 * N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :