Check if an array can be split into K non-overlapping subarrays whose Bitwise AND values are equal
Last Updated :
22 Feb, 2023
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 split 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++
#include <bits/stdc++.h>
using namespace std;
bool equalPartitionUtil( int arr[], int N, int K)
{
int pref[N][32];
memset (pref, 0, sizeof (pref));
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < 32; j++) {
if (i) {
int X = ((arr[i] & (1 << j)) > 0);
pref[i][j] = pref[i - 1][j] + X;
}
else {
pref[i][j] = ((arr[i] & (1 << j)) > 0);
}
}
}
for ( int i = 0; i < N - K + 1; i++) {
bool flag = true ;
for ( int j = 0; j < 32; j++) {
int cnt = pref[i][j];
if (cnt == i + 1
&& pref[N - 1][j] - pref[i][j] != N - i - 1)
flag = false ;
if (cnt != i + 1
&& N - i - 1 - (pref[N - 1][j] - pref[i][j]) < K - 1)
flag = false ;
}
if (flag)
return true ;
}
return false ;
}
void equalPartition( int arr[], int N, int K)
{
if (equalPartitionUtil(arr, N, K))
cout << "YES" ;
else
cout << "NO" ;
}
int main()
{
int arr[] = { 3, 2, 2, 6, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 3;
equalPartition(arr, N, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean equalPartitionUtil( int arr[],
int N, int K)
{
int [][]pref = new int [N][ 32 ];
for ( int i = 0 ; i < N; i++)
{
for ( int j = 0 ; j < 32 ; j++)
{
if (i > 0 )
{
int X = ((arr[i] & ( 1 << j)) > 0 ) ? 1 : 0 ;
pref[i][j] = pref[i - 1 ][j] + X;
}
else
{
pref[i][j] = ((arr[i] & ( 1 << j)) > 0 ) ? 1 : 0 ;
}
}
}
for ( int i = 0 ; i < N - K + 1 ; i++)
{
boolean flag = true ;
for ( int j = 0 ; j < 32 ; j++)
{
int cnt = pref[i][j];
if (cnt == i + 1 && pref[N - 1 ][j] -
pref[i][j] != N - i - 1 )
flag = false ;
if (cnt != i + 1 && N - i - 1 - (
pref[N - 1 ][j] - pref[i][j]) < K - 1 )
flag = false ;
}
if (flag)
return true ;
}
return false ;
}
static void equalPartition( int arr[], int N, int K)
{
if (equalPartitionUtil(arr, N, K))
System.out.print( "YES" );
else
System.out.print( "NO" );
}
public static void main(String[] args)
{
int arr[] = { 3 , 2 , 2 , 6 , 2 };
int N = arr.length;
int K = 3 ;
equalPartition(arr, N, K);
}
}
|
Python3
def equalPartitionUtil(arr, N, K):
pref = [[ 0 for x in range ( 32 )] for y in range (N)]
for i in range (N):
for j in range ( 32 ):
if (i):
X = ((arr[i] & ( 1 << j)) > 0 )
pref[i][j] = pref[i - 1 ][j] + X
else :
pref[i][j] = ((arr[i] & ( 1 << j)) > 0 )
for i in range (N - K + 1 ):
flag = True
for j in range ( 32 ):
cnt = pref[i][j]
if (cnt = = i + 1
and pref[N - 1 ][j] - pref[i][j] ! = N - i - 1 ):
flag = False
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
def equalPartition(arr, N, K):
if (equalPartitionUtil(arr, N, K)):
print ( "YES" )
else :
print ( "NO" )
if __name__ = = "__main__" :
arr = [ 3 , 2 , 2 , 6 , 2 ]
N = len (arr)
K = 3
equalPartition(arr, N, K)
|
C#
using System;
class GFG{
static bool equalPartitionUtil( int []arr,
int N, int K)
{
int [,]pref = new int [N, 32];
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < 32; j++)
{
if (i > 0)
{
int X = ((arr[i] & (1 << j)) > 0) ? 1 : 0;
pref[i, j] = pref[i - 1, j] + X;
}
else
{
pref[i, j] = ((arr[i] & (1 << j)) > 0) ? 1 : 0;
}
}
}
for ( int i = 0; i < N - K + 1; i++)
{
bool flag = true ;
for ( int j = 0; j < 32; j++)
{
int cnt = pref[i, j];
if (cnt == i + 1 && pref[N - 1, j] -
pref[i, j] != N - i - 1)
flag = false ;
if (cnt != i + 1 && N - i - 1 - (
pref[N - 1, j] - pref[i, j]) < K - 1)
flag = false ;
}
if (flag)
return true ;
}
return false ;
}
static void equalPartition( int []arr, int N, int K)
{
if (equalPartitionUtil(arr, N, K))
Console.Write( "YES" );
else
Console.Write( "NO" );
}
public static void Main(String[] args)
{
int []arr = { 3, 2, 2, 6, 2 };
int N = arr.Length;
int K = 3;
equalPartition(arr, N, K);
}
}
|
Javascript
<script>
function equalPartitionUtil(arr, N, K)
{
var pref = Array.from(Array(N), ()=> Array(32).fill(0));
for ( var i = 0; i < N; i++) {
for ( var j = 0; j < 32; j++) {
if (i) {
var X = ((arr[i] & (1 << j)) > 0);
pref[i][j] = pref[i - 1][j] + X;
}
else {
pref[i][j] = ((arr[i] & (1 << j)) > 0);
}
}
}
for ( var i = 0; i < N - K + 1; i++) {
var flag = true ;
for ( var j = 0; j < 32; j++) {
var cnt = pref[i][j];
if (cnt == i + 1
&& pref[N - 1][j] - pref[i][j] != N - i - 1)
flag = false ;
if (cnt != i + 1
&& N - i - 1 - (pref[N - 1][j] - pref[i][j]) < K - 1)
flag = false ;
}
if (flag)
return true ;
}
return false ;
}
function equalPartition(arr, N, K)
{
if (equalPartitionUtil(arr, N, K))
document.write( "YES" );
else
document.write( "NO" );
}
var arr = [ 3, 2, 2, 6, 2 ];
var N = arr.length;
var K = 3;
equalPartition(arr, N, K);
</script>
|
Time Complexity: O(32 * N)
Auxiliary Space: O(32 * N)
Share your thoughts in the comments
Please Login to comment...