给定n个元素的数组arr []和数K ,找到元素XOR为K的arr []的有序子集数
这是此问题的修改后的版本。因此,建议您先尝试该问题。
例子:
Input: arr[] = {6, 9, 4, 2}, k = 6
Output: 2
The subsets are {4, 2}, {2, 4} and {6}
Input: arr[] = {1, 2, 3}, k = 1
Output: 4
The subsets are {1}, {2, 3} and {3, 2}
天真的方法O(2 n ):生成所有2 n个子集,并找到所有具有XOR值K的子集,并为每个具有XOR值K的子集添加no。子集对答案的排列,因为我们需要有序子集,但是这种方法对于n较大的值将无效。
高效方法O(n 2 * m):此方法使用动态编程,与本文介绍的方法相似。
唯一的修改是我们在解决方案中增加了一个状态。那里有两个状态,其中dp [i] [j]存储了否。 XOR值为j的数组[0…i-1]的子集的数量。现在,我们再添加一个状态k ,即存储子集长度的第三维。
因此, dp [i] [j] [k]将存储编号。具有XOR值j的数组[0…i-1]的长度k的子集的集合。
现在我们可以看到
即dp [i] [j] [k]可以通过丢弃a [i]元素(给出dp [i-1] [j] [k]子集)并将其放入子集中来找到(与子集相似)求和问题)给出dp [i-1] [a [i] ^ j] [k-1]个子集。现在我们必须在k – 1个长度子集中插入a [i]元素,这可以用k种方式来完成,这可以解释k的因数。
换上dp阵列后,我们的答案将是
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Returns count of ordered subsets of arr[]
// with XOR value = K
int subsetXOR(int arr[], int n, int K)
{
// Find maximum element in arr[]
int max_ele = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max_ele)
max_ele = arr[i];
// Maximum possible XOR value
int m = (1 << (int)(log2(max_ele) + 1)) - 1;
// The value of dp[i][j][k] is the number
// of subsets of length k having XOR of their
// elements as j from the set arr[0...i-1]
int dp[n + 1][m + 1][n + 1];
// Initializing all the values of dp[i][j][k]
// as 0
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= n; k++)
dp[i][j][k] = 0;
// The xor of empty subset is 0
for (int i = 0; i <= n; i++)
dp[i][0][0] = 1;
// Fill the dp table
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= n; k++) {
dp[i][j][k] = dp[i - 1][j][k];
if (k != 0) {
dp[i][j][k] += k * dp[i - 1][j ^
arr[i - 1]][k - 1];
}
}
}
}
// The answer is the number of subsets of all lengths
// from set arr[0..n-1] having XOR of elements as k
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += dp[n][K][i];
}
return ans;
}
// Driver program to test above function
int main()
{
int arr[] = { 1, 2, 3 };
int k = 1;
int n = sizeof(arr) / sizeof(arr[0]);
cout << subsetXOR(arr, n, k);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Returns count of ordered subsets of arr[]
// with XOR value = K
static int subsetXOR(int arr[], int n, int K)
{
// Find maximum element in arr[]
int max_ele = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max_ele)
max_ele = arr[i];
// Maximum possible XOR value
int m = (1 << (int)(Math.log(max_ele) /
Math.log(2) + 1)) - 1;
// The value of dp[i][j][k] is the number
// of subsets of length k having XOR of their
// elements as j from the set arr[0...i-1]
int [][][] dp = new int[n + 1][m + 1][n + 1];
// Initializing all the values of
// dp[i][j][k] as 0
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= n; k++)
dp[i][j][k] = 0;
// The xor of empty subset is 0
for (int i = 0; i <= n; i++)
dp[i][0][0] = 1;
// Fill the dp table
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
for (int k = 0; k <= n; k++)
{
dp[i][j][k] = dp[i - 1][j][k];
if (k != 0)
{
dp[i][j][k] += k * dp[i - 1][j ^
arr[i - 1]][k - 1];
}
}
}
}
// The answer is the number of subsets
// of all lengths from set arr[0..n-1]
// having XOR of elements as k
int ans = 0;
for (int i = 1; i <= n; i++)
{
ans += dp[n][K][i];
}
return ans;
}
// Driver code
public static void main(String []args)
{
int arr[] = { 1, 2, 3 };
int k = 1;
int n = arr.length;
System.out.println(subsetXOR(arr, n, k));
}
}
// This code is contributed by ihritik
Python3
# Python 3implementation of the approach
from math import log2
# Returns count of ordered subsets of arr[]
# with XOR value = K
def subsetXOR(arr, n, K):
# Find maximum element in arr[]
max_ele = arr[0]
for i in range(1, n):
if (arr[i] > max_ele):
max_ele = arr[i]
# Maximum possible XOR value
m = (1 << int(log2(max_ele) + 1)) - 1
# The value of dp[i][j][k] is the number
# of subsets of length k having XOR of their
# elements as j from the set arr[0...i-1]
dp = [[[0 for i in range(n + 1)]
for j in range(m + 1)]
for k in range(n + 1)]
# Initializing all the values
# of dp[i][j][k] as 0
for i in range(n + 1):
for j in range(m + 1):
for k in range(n + 1):
dp[i][j][k] = 0
# The xor of empty subset is 0
for i in range(n + 1):
dp[i][0][0] = 1
# Fill the dp table
for i in range(1, n + 1):
for j in range(m + 1):
for k in range(n + 1):
dp[i][j][k] = dp[i - 1][j][k]
if (k != 0):
dp[i][j][k] += k * dp[i - 1][j ^ arr[i - 1]][k - 1]
# The answer is the number of subsets of all lengths
# from set arr[0..n-1] having XOR of elements as k
ans = 0
for i in range(1, n + 1):
ans += dp[n][K][i]
return ans
# Driver Code
if __name__ == '__main__':
arr = [1, 2, 3]
k = 1
n = len(arr)
print(subsetXOR(arr, n, k))
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the approach
using System;
class GFG
{
// Returns count of ordered subsets of arr[]
// with XOR value = K
static int subsetXOR(int []arr, int n, int K)
{
// Find maximum element in arr[]
int max_ele = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max_ele)
max_ele = arr[i];
// Maximum possible XOR value
int m = (1 << (int)(Math.Log(max_ele) /
Math.Log(2) + 1)) - 1;
// The value of dp[i][j][k] is the number
// of subsets of length k having XOR of their
// elements as j from the set arr[0...i-1]
int [ , , ] dp = new int[n + 1 , m + 1 ,n + 1];
// Initializing all the values of
// dp[i][j][k] as 0
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= n; k++)
dp[i, j, k] = 0;
// The xor of empty subset is 0
for (int i = 0; i <= n; i++)
dp[i, 0, 0] = 1;
// Fill the dp table
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
for (int k = 0; k <= n; k++)
{
dp[i, j, k] = dp[i - 1, j, k];
if (k != 0) {
dp[i, j, k] += k * dp[i - 1, j ^
arr[i - 1], k - 1];
}
}
}
}
// The answer is the number of subsets
// of all lengths from set arr[0..n-1]
// having XOR of elements as k
int ans = 0;
for (int i = 1; i <= n; i++)
{
ans += dp[n, K, i];
}
return ans;
}
// Driver code
public static void Main()
{
int []arr = { 1, 2, 3 };
int k = 1;
int n = arr.Length;
Console.WriteLine(subsetXOR(arr, n, k));
}
}
// This code is contributed by ihritik
PHP
$max_ele)
$max_ele = $arr[$i];
// Maximum possible XOR value
$m = (1 << (floor(log($max_ele, 2))+ 1)) - 1;
// The value of dp[i][j][k] is the number
// of subsets of length k having XOR of their
// elements as j from the set arr[0...i-1]
$dp = array(array(array())) ;
// Initializing all the values
// of dp[i][j][k] as 0
for ($i = 0; $i <= $n; $i++)
for ($j = 0; $j <= $m; $j++)
for ($k = 0; $k <= $n; $k++)
$dp[$i][$j][$k] = 0;
// The xor of empty subset is 0
for ($i = 0; $i <= $n; $i++)
$dp[$i][0][0] = 1;
// Fill the dp table
for ($i = 1; $i <= $n; $i++)
{
for ($j = 0; $j <= $m; $j++)
{
for ($k = 0; $k <= $n; $k++)
{
$dp[$i][$j][$k] = $dp[$i - 1][$j][$k];
if ($k != 0)
{
$dp[$i][$j][$k] += $k * $dp[$i - 1][$j ^
$arr[$i - 1]][$k - 1];
}
}
}
}
// The answer is the number of subsets
// of all lengths from set arr[0..n-1]
// having XOR of elements as k
$ans = 0;
for ($i = 1; $i <= $n; $i++)
{
$ans += $dp[$n][$K][$i];
}
return $ans;
}
// Driver Code
$arr = [ 1, 2, 3 ];
$k = 1;
$n = sizeof($arr);
echo subsetXOR($arr, $n, $k);
// This code is contributed by Ryuga
?>
3