生成范围 [0, N-1] 中的对,其中所有对 K 的按位与之和
给定一个整数N (它始终是 2 的幂),表示一个数组的长度,该数组仅包含一次[0, N-1]范围内的整数,任务是以一种方式将这些元素配对,使得对的AND等于K。即∑ (a i & b i ) = K。
注意:每个元素只能是一对的一部分。
例子:
Input: N = 4, K = 2
Output: [[0, 1], [2, 3]]
Explanation: Here N = 4 means array contains arr[] = {0, 1, 2, 3},
Pairs = [0, 1] and [2, 3]
(0 & 1) + (2 & 3) = 0 + 2 = 2.
Input: N = 8, K = 4
Output: [[4, 7], [1, 6], [2, 5], [0, 3]]
方法:该问题的解决方案基于以下观察:
There can be four cases as shown below:
- Case 1 (If K = 0):
- Because N is power of 2, the pairs of form {0+i, N-1-i} will always have bitwise AND as 0 [where i = 0 to (N-1)/2].
- Here AND of every pair is going to be 0 which implies the sum of every AND pair is going to be 0.
- After that for K = 0 form these pairs in the following form: [[0, N-1], [1, N-2] . . .].
- Case 2 (If K > 0 and K < N-1):
- Bitwise AND of K with N-1 is always K.
- From the above pairs, exchanging only elements of two pairs and make pairs [K, N-1] and [0, the one which was a pair of K]. So the AND will be K.
- Case 3 (If K = N-1 and N = 4):
- In this case pairing is not possible print -1.
- Case 4 (If K = N-1 and N > 4):
- The maximum AND of any pair can be N-2 which can be formed by N-1 and N-2. So other two pairs can be formed to have bitwise AND =1 i.e. (N-3 with 1) and (0 with 2) because N-3 and 1 are always odd. The other pairs can be kept as it was in case-1. So total bitwise AND sum will be N-1.
请按照以下步骤操作:
- 检查K和N的值。
- 根据 N 和 K 的值,按上述情况组成对。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to print N-1 Pairs
void pairOfAND(int N, int K)
{
// Initializing ans which contains
// AND pairs having sum equal to K
vector > ans;
// Case 1 and Case 2
if (K >= 0 || K < N - 1) {
// Hash Map contains pairs
map pair;
for (int i = 0, j = N - 1; i < N / 2; i++, j--) {
pair.insert({ i, j });
pair.insert({ j, i });
}
// Case 1
if (K == 0) {
for (int i = 0; i < N / 2; i++) {
vector al;
al.push_back(i);
al.push_back(pair[i]);
ans.push_back(al);
}
}
// Case 2
else if (K < N / 2) {
vector al;
al.push_back(K);
al.push_back(N - 1);
ans.push_back(al);
for (int i = 1; i < N / 2; i++) {
al = {};
al.push_back((i == K) ? 0 : i);
al.push_back(pair[i]);
ans.push_back(al);
}
}
else {
vector al;
al.push_back(K);
al.push_back(N - 1);
ans.push_back(al);
for (int i = N / 2; i < N - 1; i++) {
al = {};
al.push_back((i == K) ? 0 : i);
al.push_back(pair[i]);
ans.push_back(al);
}
}
}
// Case 4
else {
if (N != 4) {
vector al;
al.push_back(N - 1);
al.push_back(N - 2);
ans.push_back(al);
al = {};
al.push_back(N - 3);
al.push_back(1);
ans.push_back(al);
al = {};
al.push_back(0);
al.push_back(2);
ans.push_back(al);
for (int i = 3; i < N / 2; i++) {
al = {};
int comp = i ^ (N - 1);
al.push_back(i);
al.push_back(comp);
ans.push_back(al);
}
}
}
// Case 3
if (ans.size() == 0)
cout << (-1);
else
for (auto arr : ans) {
for (auto dt : arr)
cout << dt << " ";
cout << "\n";
}
}
// Driver Code
int main()
{
int N = 4;
int K = 2;
pairOfAND(N, K);
return 0;
}
// This code is contributed by rakeshsahnis
Java
// Java code to implement the above approach
import java.util.*;
class GFG {
// Function to print N-1 Pairs
public static void pairOfAND(int N,
int K)
{
// Initializing ans which contains
// AND pairs having sum equal to K
List > ans
= new ArrayList<>();
// Case 1 and Case 2
if (K >= 0 || K < N - 1) {
// Hash Map contains pairs
Map pair
= new HashMap<>();
for (int i = 0, j = N - 1;
i < N / 2;
i++, j--) {
pair.put(i, j);
pair.put(j, i);
}
// Case 1
if (K == 0) {
for (int i = 0; i < N / 2;
i++) {
List al
= new ArrayList<>();
al.add(i);
al.add(pair.get(i));
ans.add(al);
}
}
// Case 2
else if (K < N / 2) {
List al
= new ArrayList<>();
al.add(K);
al.add(N - 1);
ans.add(al);
for (int i = 1; i < N / 2;
i++) {
al = new ArrayList<>();
al.add((i == K) ? 0 : i);
al.add(pair.get(i));
ans.add(al);
}
}
else {
List al
= new ArrayList<>();
al.add(K);
al.add(N - 1);
ans.add(al);
for (int i = N / 2; i < N - 1;
i++) {
al = new ArrayList<>();
al.add((i == K) ? 0 : i);
al.add(pair.get(i));
ans.add(al);
}
}
}
// Case 4
else {
if (N != 4) {
List al
= new ArrayList<>();
al.add(N - 1);
al.add(N - 2);
ans.add(al);
al = new ArrayList<>();
al.add(N - 3);
al.add(1);
ans.add(al);
al = new ArrayList<>();
al.add(0);
al.add(2);
ans.add(al);
for (int i = 3; i < N / 2;
i++) {
al = new ArrayList<>();
int comp = i ^ (N - 1);
al.add(i);
al.add(comp);
ans.add(al);
}
}
}
// Case 3
if (ans.isEmpty())
System.out.println(-1);
else
System.out.println(ans);
}
// Driver Code
public static void main(String[] args)
{
int N = 4;
int K = 2;
pairOfAND(N, K);
}
}
输出
[[2, 3], [0, 1]]
时间复杂度: O(N)
辅助空间: O(N)