计算将数组拆分为三个具有相等按位异或值的非空子数组的方法
给定一个由N个非负整数组成的数组arr[] ,任务是计算将数组拆分为三个不同的非空子数组的方式的数量,以使每个子数组的按位异或相等。
例子:
Input: arr[] = {7, 0, 5, 2, 7}
Output: 2
Explanation: All possible ways are:
{{7}, {0, 5, 2}, {7}} where XOR value of each subarray is 7
{{7, 0}, {5, 2}, {7}} where XOR value of each subarray is 7
Input: arr[] = {3, 1, 4}
Output: 0
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的每个前缀数组的终点。
- 创建另一个数组,大小为N的suff_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)