给定大小为N的数组arr []和正整数K ,任务是检查该数组是否可以拆分为K个非重叠和非空子数组,以使所有子数组的按位与相等。如果发现是真的,则打印“是” 。否则,打印“否” 。
例子:
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
天真的方法:解决此问题的最简单方法是,以所有可能的方式将数组拆分为K个子数组,并以每种可能的方式检查所有K个子数组的按位与是否相等。如果发现任何拆分均成立,则打印“是” 。否则,打印“否” 。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效方法:为了优化上述方法中,想法是使用以下事实:如果i中的子阵列的至少一个元件的第i位是0,则第i个该子阵列的按位的位AND也为0。请按照以下步骤解决问题:
- 初始化一个变量,例如flag ,以检查该数组是否可以放入K个子数组中,以使所有子数组的按位与相等。
- 初始化一个2D数组,例如pref [] [] ,其中pref [i] [j]存储直到第i个索引(其第j个位被设置)的连续数组元素的数量。
- 在[0,N – K]范围内迭代。对于第i个元素的第j个位,请检查以下条件:
- 如果j所有的数组元素的第i位到第i个索引被设置并且第i个指数没有被设置,则更新标志=假后第j个所述阵列中的至少一个元素的位。
- 如果j的至少一个数组元素多达第i索引的第i位不是第i个索引被设置然后更新标志=假之后设置和第j所有的数组元素的位
- 最后,检查标志是否等于true。如果发现是真的,则打印“是” 。
- 否则,打印“否” 。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
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;
}
Java
// 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
Python3
# 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.
C#
// 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
Javascript
输出:
YES
时间复杂度: O(32 * N)
辅助空间: O(32 * N)