📌  相关文章
📜  计算将数组拆分为三个具有相等按位异或值的非空子数组的方法

📅  最后修改于: 2022-05-13 01:56:07.992000             🧑  作者: Mango

计算将数组拆分为三个具有相等按位异或值的非空子数组的方法

给定一个由N个非负整数组成的数组arr[] ,任务是计算将数组拆分为三个不同的非空子数组的方式的数量,以使每个子数组的按位异或相等。

例子:

Naive Approach:最简单的方法是使用三个循环将数组拆分为三个非空子数组,并检查每个子数组的 XOR 是否相等。如果给定条件成立,则增加最终计数。打印获得的最终计数。

时间复杂度: O(N 3 )
辅助空间: O(1)

有效方法:上述方法可以根据以下观察进行优化:

  • xor_arr为数组arr[]的所有元素的 XOR。
  • 如果arr[]可以分成三个具有相同 XOR 值的不同子数组,则每个子数组中所有元素的 XOR 将等于xor_arr
  • 因此,我们的想法是找到所有XOR值等于xor_arr的前缀和后缀数组。
  • 如果这样的前缀和后缀数组的总长度小于 N,则它们之间存在另一个子数组,其 XOR 值等于xor_arr

因此,计算所有满足上述条件的前缀和后缀数组的总数。请按照以下步骤解决给定的问题:

  • 将数组的所有元素arr[]的 XOR 存储在变量xor_arr中。
  • 创建一个数组pref_ind[]来存储 XOR 值等于xor_arr的每个前缀数组的终点。
  • 遍历数组arr[]并在 pref_ind 中插入 XOR 值等于xor_arr的每个前缀数组的终点
  • 创建另一个数组,大小为Nsuff_inds[] ,其中suff_inds[i]存储 XOR 值等于xor_arr 且起点大于或等于i的后缀数组的总数。
  • 遍历数组,以相反的顺序arr[]填充suff_inds[]数组。如果当前后缀数组 XOR 值等于xor_arr ,则将suff_inds[i]增加1 。此外,将suff_inds[i+1]的值添加到suff_inds[i]
  • 对于pref_ind中的每个元素idx ,如果idx < N-1的值,则将 suff_inds[idx + 2]的值添加到最终计数中。
  • 最后,打印最终计数的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count ways to split array
// into three subarrays with equal Bitwise XOR
int countWays(int arr[], int N)
{
    // Stores the XOR value of arr[]
    int arr_xor = 0;
 
    // Update the value of arr_xor
    for (int i = 0; i < N; i++)
        arr_xor ^= arr[i];
 
    // Stores the XOR value of prefix
    // and suffix array respectively
    int pref_xor = 0, suff_xor = 0;
 
    // Stores the ending points of all
    // the required prefix arrays
    vector pref_ind;
 
    // Stores the count of suffix arrays
    // whose XOR value is equal to the
    // total XOR value at each index
    int suff_inds[N + 1];
    memset(suff_inds, 0, sizeof suff_inds);
 
    // Find all prefix arrays with
    // XOR value equal to arr_xor
    for (int i = 0; i < N; i++) {
 
        // Update pref_xor
        pref_xor ^= arr[i];
 
        if (pref_xor == arr_xor)
            pref_ind.push_back(i);
    }
 
    // Fill the values of suff_inds[]
    for (int i = N - 1; i >= 0; i--) {
 
        // Update suff_xor
        suff_xor ^= arr[i];
 
        // Update suff_inds[i]
        suff_inds[i] += suff_inds[i + 1];
 
        if (suff_xor == arr_xor)
            suff_inds[i]++;
    }
 
    // Stores the total number of ways
    int tot_ways = 0;
 
    // Count total number of ways
    for (int idx : pref_ind) {
        if (idx < N - 1)
            tot_ways += suff_inds[idx + 2];
    }
 
    // Return the final count
    return tot_ways;
}
 
// Driver Code
int main()
{
    // Given Input
    int arr[] = { 7, 0, 5, 2, 7 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    cout << countWays(arr, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.lang.*;
import java.util.*;
 
class GFG
{
 
  // Function to count ways to split array
  // into three subarrays with equal Bitwise XOR
  static int countWays(int arr[], int N)
  {
 
    // Stores the XOR value of arr[]
    int arr_xor = 0;
 
    // Update the value of arr_xor
    for (int i = 0; i < N; i++)
      arr_xor ^= arr[i];
 
    // Stores the XOR value of prefix
    // and suffix array respectively
    int pref_xor = 0, suff_xor = 0;
 
    // Stores the ending points of all
    // the required prefix arrays
    ArrayList pref_ind=new ArrayList<>();
 
    // Stores the count of suffix arrays
    // whose XOR value is equal to the
    // total XOR value at each index
    int[] suff_inds= new int[N + 1];
 
    // Find all prefix arrays with
    // XOR value equal to arr_xor
    for (int i = 0; i < N; i++) {
 
      // Update pref_xor
      pref_xor ^= arr[i];
 
      if (pref_xor == arr_xor)
        pref_ind.add(i);
    }
 
    // Fill the values of suff_inds[]
    for (int i = N - 1; i >= 0; i--) {
 
      // Update suff_xor
      suff_xor ^= arr[i];
 
      // Update suff_inds[i]
      suff_inds[i] += suff_inds[i + 1];
 
      if (suff_xor == arr_xor)
        suff_inds[i]++;
    }
 
    // Stores the total number of ways
    int tot_ways = 0;
 
    // Count total number of ways
    for (Integer idx : pref_ind) {
      if (idx < N - 1)
        tot_ways += suff_inds[idx + 2];
    }
 
    // Return the final count
    return tot_ways;
  }
 
  // Driver code
  public static void main(String[] args)
  {
 
    // Given Input
    int arr[] = { 7, 0, 5, 2, 7 };
    int N = arr.length;
 
    // Function Call
    System.out.println(countWays(arr, N));
 
  }
 
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
 
# Function to count ways to split array
# into three subarrays with equal Bitwise XOR
def countWays(arr, N):
     
    # Stores the XOR value of arr[]
    arr_xor = 0
 
    # Update the value of arr_xor
    for i in range(N):
        arr_xor ^= arr[i]
 
    # Stores the XOR value of prefix
    # and suffix array respectively
    pref_xor, suff_xor = 0, 0
 
    # Stores the ending points of all
    # the required prefix arrays
    pref_ind = []
 
    # Stores the count of suffix arrays
    # whose XOR value is equal to the
    # total XOR value at each index
    suff_inds = [0] * (N + 1)
    # memset(suff_inds, 0, sizeof suff_inds)
 
    # Find all prefix arrays with
    # XOR value equal to arr_xor
    for i in range(N):
 
        # Update pref_xor
        pref_xor ^= arr[i]
 
        if (pref_xor == arr_xor):
            pref_ind.append(i)
 
    # Fill the values of suff_inds[]
    for i in range(N - 1, -1, -1):
         
        # Update suff_xor
        suff_xor ^= arr[i]
 
        # Update suff_inds[i]
        suff_inds[i] += suff_inds[i + 1]
 
        if (suff_xor == arr_xor):
            suff_inds[i] += 1
 
    # Stores the total number of ways
    tot_ways = 0
 
    # Count total number of ways
    for idx in pref_ind:
        if (idx < N - 1):
            tot_ways += suff_inds[idx + 2]
 
    # Return the final count
    return tot_ways
 
# Driver Code
if __name__ == '__main__':
     
    # Given Input
    arr = [ 7, 0, 5, 2, 7 ]
    N = len(arr)
 
    # Function Call
    print (countWays(arr, N))
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
 
    // Function to count ways to split array
    // into three subarrays with equal Bitwise XOR
    static int countWays(int[] arr, int N)
    {
 
        // Stores the XOR value of arr[]
        int arr_xor = 0;
 
        // Update the value of arr_xor
        for (int i = 0; i < N; i++)
            arr_xor ^= arr[i];
 
        // Stores the XOR value of prefix
        // and suffix array respectively
        int pref_xor = 0, suff_xor = 0;
 
        // Stores the ending points of all
        // the required prefix arrays
        List pref_ind = new List();
 
        // Stores the count of suffix arrays
        // whose XOR value is equal to the
        // total XOR value at each index
        int[] suff_inds = new int[N + 1];
 
        // Find all prefix arrays with
        // XOR value equal to arr_xor
        for (int i = 0; i < N; i++) {
 
            // Update pref_xor
            pref_xor ^= arr[i];
 
            if (pref_xor == arr_xor)
                pref_ind.Add(i);
        }
 
        // Fill the values of suff_inds[]
        for (int i = N - 1; i >= 0; i--) {
 
            // Update suff_xor
            suff_xor ^= arr[i];
 
            // Update suff_inds[i]
            suff_inds[i] += suff_inds[i + 1];
 
            if (suff_xor == arr_xor)
                suff_inds[i]++;
        }
 
        // Stores the total number of ways
        int tot_ways = 0;
 
        // Count total number of ways
        foreach(int idx in pref_ind)
        {
            if (idx < N - 1)
                tot_ways += suff_inds[idx + 2];
        }
 
        // Return the final count
        return tot_ways;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
 
        // Given Input
        int[] arr = { 7, 0, 5, 2, 7 };
        int N = arr.Length;
 
        // Function Call
        Console.WriteLine(countWays(arr, N));
    }
}
 
// This code is contributed by ukasp.


Javascript


输出:
2

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