给定一组正整数。在给定集合中找到最大XOR子集值。预期时间复杂度O(n)。
例子:
Input: set[] = {2, 4, 5}
Output: 7
The subset {2, 5} has maximum XOR value
Input: set[] = {9, 8, 5}
Output: 13
The subset {8, 5} has maximum XOR value
Input: set[] = {8, 1, 2, 12, 7, 6}
Output: 15
The subset {1, 2, 12} has maximum XOR value
Input: set[] = {4, 6}
Output: 6
The subset {6} has maximum XOR value
请注意,此问题与最大子数组XOR不同。在这里,我们需要找到子集而不是子数组。
一个简单的解决方案是生成给定集合的所有可能子集,找到每个子集的XOR,然后以最大XOR返回该子集。
以下是在O(n)时间内有效的高效算法。
这个想法基于以下事实:
- 表示所有元素的位数是固定的,在大多数编译器中,整数是32位。
- 如果最大元素在位置i处具有最高有效位MSB,则结果至少为2 i
1. Initialize index of chosen elements as 0. Let this index be
'index'
2. Traverse through all bits starting from most significant bit.
Let i be the current bit.
......(a) Find the maximum element with i'th bit set. If there
is no element with i'th bit set, continue to smaller
bit.
......(b) Let the element with i'th bit set be maxEle and index
of this element be maxInd. Place maxEle at 'index' and
(by swapping set[index] and set[maxInd])
......(c) Do XOR of maxEle with all numbers having i'th bit as set.
......(d) Increment index
3. Return XOR of all elements in set[]. Note that set[] is modified
in step 2.c.
下面是该算法的实现。
C++
// C++ program to find
// maximum XOR subset
#include
using namespace std;
// Number of bits to
// represent int
#define INT_BITS 32
// Function to return
// maximum XOR subset
// in set[]
int maxSubarrayXOR(int set[], int n)
{
// Initialize index of
// chosen elements
int index = 0;
// Traverse through all
// bits of integer
// starting from the most
// significant bit (MSB)
for (int i = INT_BITS-1; i >= 0; i--)
{
// Initialize index of
// maximum element and
// the maximum element
int maxInd = index;
int maxEle = INT_MIN;
for (int j = index; j < n; j++)
{
// If i'th bit of set[j]
// is set and set[j] is
// greater than max so far.
if ( (set[j] & (1 << i)) != 0
&& set[j] > maxEle )
maxEle = set[j], maxInd = j;
}
// If there was no
// element with i'th
// bit set, move to
// smaller i
if (maxEle == INT_MIN)
continue;
// Put maximum element
// with i'th bit set
// at index 'index'
swap(set[index], set[maxInd]);
// Update maxInd and
// increment index
maxInd = index;
// Do XOR of set[maxIndex]
// with all numbers having
// i'th bit as set.
for (int j=0; j
Java
// Java program to find
// maximum XOR subset
import java.util.*;
class GFG {
// Number of bits to
// represent int
static final int INT_BITS = 32;
// Function to return
// maximum XOR subset
// in set[]
static int maxSubarrayXOR(int set[], int n)
{
// Initialize index of
// chosen elements
int index = 0;
// Traverse through all
// bits of integer
// starting from the most
// significant bit (MSB)
for (int i = INT_BITS - 1; i >= 0; i--)
{
// Initialize index of
// maximum element and
// the maximum element
int maxInd = index;
int maxEle = Integer.MIN_VALUE;
for (int j = index; j < n; j++) {
// If i'th bit of set[j]
// is set and set[j] is
// greater than max so far.
if ((set[j] & (1 << i)) != 0 && set[j] > maxEle)
{
maxEle = set[j];
maxInd = j;
}
}
// If there was no
// element with i'th
// bit set, move to
// smaller i
if (maxEle == -2147483648)
continue;
// Put maximum element
// with i'th bit set
// at index 'index'
int temp = set[index];
set[index] = set[maxInd];
set[maxInd] = temp;
// Update maxInd and
// increment index
maxInd = index;
// Do XOR of set[maxIndex]
// with all numbers having
// i'th bit as set.
for (int j = 0; j < n; j++) {
// XOR set[maxInd] those
// numbers which have the
// i'th bit set
if (j != maxInd && (set[j] & (1 << i)) != 0)
set[j] = set[j] ^ set[maxInd];
}
// Increment index of
// chosen elements
index++;
}
// Final result is
// XOR of all elements
int res = 0;
for (int i = 0; i < n; i++)
res ^= set[i];
return res;
}
// Driver code
public static void main(String arg[]) {
int set[] = {9, 8, 5};
int n = set.length;
System.out.print("Max subset XOR is ");
System.out.print(maxSubarrayXOR(set, n));
}
}
// This code is contributed by Anant Agarwal.
Python3
# Python program to find
# maximum XOR subset
# Number of bits to
# represent int
INT_BITS=32
# Function to return
# maximum XOR subset
# in set[]
def maxSubarrayXOR(set,n):
# Initialize index of
# chosen elements
index = 0
# Traverse through all
# bits of integer
# starting from the most
# significant bit (MSB)
for i in range(INT_BITS-1,-1,-1):
# Initialize index of
# maximum element and
# the maximum element
maxInd = index
maxEle = -2147483648
for j in range(index,n):
# If i'th bit of set[j]
# is set and set[j] is
# greater than max so far.
if ( (set[j] & (1 << i)) != 0
and set[j] > maxEle ):
maxEle = set[j]
maxInd = j
# If there was no
# element with i'th
# bit set, move to
# smaller i
if (maxEle ==-2147483648):
continue
# Put maximum element
# with i'th bit set
# at index 'index'
temp=set[index]
set[index]=set[maxInd]
set[maxInd]=temp
# Update maxInd and
# increment index
maxInd = index
# Do XOR of set[maxIndex]
# with all numbers having
# i'th bit as set.
for j in range(n):
# XOR set[maxInd] those
# numbers which have the
# i'th bit set
if (j != maxInd and
(set[j] & (1 << i)) != 0):
set[j] = set[j] ^ set[maxInd]
# Increment index of
# chosen elements
index=index + 1
# Final result is
# XOR of all elements
res = 0
for i in range(n):
res =res ^ set[i]
return res
# Driver code
set= [9, 8, 5]
n =len(set)
print("Max subset XOR is ",end="")
print(maxSubarrayXOR(set, n))
# This code is contributed
# by Anant Agarwal.
C#
// C# program to find
// maximum XOR subset
using System;
class GFG
{
// Number of bits to
// represent int
static int INT_BITS = 32;
// Function to return
// maximum XOR subset
// in set[]
static int maxSubarrayXOR(int []set,
int n)
{
// Initialize index of
// chosen elements
int index = 0;
// Traverse through all
// bits of integer
// starting from the most
// significant bit (MSB)
for (int i = INT_BITS - 1;
i >= 0; i--)
{
// Initialize index of
// maximum element and
// the maximum element
int maxInd = index;
int maxEle = int.MinValue;
for (int j = index; j < n; j++)
{
// If i'th bit of set[j]
// is set and set[j] is
// greater than max so far.
if ((set[j] & (1 << i)) != 0 &&
set[j] > maxEle)
{
maxEle = set[j];
maxInd = j;
}
}
// If there was no
// element with i'th
// bit set, move to
// smaller i
if (maxEle == -2147483648)
continue;
// Put maximum element
// with i'th bit set
// at index 'index'
int temp = set[index];
set[index] = set[maxInd];
set[maxInd] = temp;
// Update maxInd and
// increment index
maxInd = index;
// Do XOR of set[maxIndex]
// with all numbers having
// i'th bit as set.
for (int j = 0; j < n; j++)
{
// XOR set[maxInd] those
// numbers which have the
// i'th bit set
if (j != maxInd && (set[j] &
(1 << i)) != 0)
set[j] = set[j] ^ set[maxInd];
}
// Increment index of
// chosen elements
index++;
}
// Final result is
// XOR of all elements
int res = 0;
for (int i = 0; i < n; i++)
res ^= set[i];
return res;
}
// Driver code
public static void Main()
{
int []set = {9, 8, 5};
int n = set.Length;
Console.Write("Max subset XOR is ");
Console.Write(maxSubarrayXOR(set, n));
}
}
// This code is contributed by Sam007.
PHP
= 0; $i--)
{
// Initialize index of maximum element
// and the maximum element
$maxInd = $index;
$maxEle = 0;
for ($j = $index; $j < $n; $j++)
{
// If i'th bit of set[j]
// is set and set[j] is
// greater than max so far.
if ( ($set[$j] & (1 << $i)) != 0 &&
$set[$j] > $maxEle )
{
$maxEle = $set[$j];
$maxInd = $j;
}
}
// If there was no element with i'th
// bit set, move to smaller i
if ($maxEle == 0)
continue;
// Put maximum element with i'th bit
// set at index 'index'
$t = $set[$index];
$set[$index] = $set[$maxInd];
$set[$maxInd] = $t;
// Update maxInd and increment index
$maxInd = $index;
// Do XOR of set[maxIndex] with all numbers
// having i'th bit as set.
for ($j = 0; $j < $n; $j++)
{
// XOR set[maxInd] those numbers which
// have the i'th bit set
if ($j != $maxInd &&
($set[$j] & (1 << $i)) != 0)
$set[$j] = $set[$j] ^ $set[$maxInd];
}
// Increment index of chosen elements
$index++;
}
// Final result is XOR of all elements
$res = 0;
for ($i = 0; $i < $n; $i++)
$res ^= $set[$i];
return $res;
}
// Driver Code
$set = array(9, 8, 5);
$n = sizeof($set);
echo "Max subset XOR is ";
echo maxSubarrayXOR($set, $n);
// This code is contributed by ita_c
?>
Javascript
输出:
Max subset XOR is 13
插图:
Let the input set be : {9, 8, 5}
We start from 31st bit [Assuming Integers are 32 bit
long]. The loop will continue without doing anything till 4'th bit.
The 4th bit is set in set[0] i.e. 9 and this is the maximum
element with 4th bit set. So we choose this element and check
if any other number has the same bit set. If yes, we XOR that
number with 9. The element set[1], i.e., 8 also has 4'th bit
set. Now set[] becomes {9, 1, 5}. We add 9 to the list of
chosen elements by incrementing 'index'
We move further and find the maximum number with 3rd bit set
which is set[2] i.e. 5 No other number in the array has 3rd
bit set. 5 is also added to the list of chosen element.
We then iterate for bit 2 (no number for this) and then for
1 which is 1. But numbers 9 and 5 have the 1st bit set. Thus
we XOR 9 and 5 with 1 and our set becomes (8, 1, 4)
Finally, we XOR current elements of set and get the result
as 8 ^ 1 ^ 4 = 13.