📌  相关文章
📜  检查数组是否可以拆分为按位与值相等的K个非重叠子数组

📅  最后修改于: 2021-05-13 22:50:23             🧑  作者: Mango

给定大小为N的数组arr []和正整数K ,任务是检查该数组是否可以拆分为K个非重叠和非空子数组,以使所有子数组的按位与相等。如果发现是真的,则打印“是” 。否则,打印“否”

例子:

天真的方法:解决此问题的最简单方法是,以所有可能的方式将数组拆分为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


输出:
YES

时间复杂度: O(32 * N)
辅助空间: O(32 * N)