给定两个整数N和S,所述任务是从区间[0,2(N – 1)]发现数字的圆形排列,与S开始,使得任何一对相邻的数字之间的不匹配比特的数量是一个。
例子:
Input: N = 2, S = 3
Output: [3, 2, 0, 1]
Explanation:
The binary representation of numbers 3, 2, 0 and 1 are “11”, “10”, “01” and “00” respectively.
Therefore, arranging them in the order [3, 2, 0, 1] ensures that the number of bit differences between each pair of adjacent elements (circular) is 1.
Input: N = 3, S = 2
Output: [2, 6, 7, 5, 4, 0, 1, 3]
方法:可以根据以下观察结果解决给定问题:
- A simple observation is that the numbers in the range [2i, 2i + 1 – 1] can be obtained in their natural order by placing ‘1’s before each number in the range [0, 2i – 1].
- Therefore, the problem can be solved recursively by adding ‘1’ before each number before 2i – 1th index and reverse it before appending the new numbers to permutation.
请按照以下步骤解决问题:
- 初始化一个列表,例如res ,以存储所需的排列。
- 初始化一个整数,例如index ,以存储S在从0开始的置换中的位置。
- 在[0,N – 1]范围内进行迭代,并以相反的顺序遍历数组res []并检查当前数字和2 i的和是否为S。如果发现是真的,则使用res的当前索引更新index ,并将当前数字+ 2 i追加到res列表中。
- 按索引位置旋转列表res []。
- 完成上述步骤后,打印列表res []作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the permutation of
// integers from a given range such that
// number of mismatching bits between
// pairs of adjacent elements is 1
vector circularPermutation(int n, int start)
{
// Initialize an arrayList to
// store the resultant permutation
vector res = {0};
vector ret;
// Store the index of rotation
int index = -1;
// Iterate over the range [0, N - 1]
for(int k = 0, add = 1 << k; k < n;
k++, add = 1 << k)
{
// Traverse all the array elements
// up to (2 ^ k)-th index in reverse
for (int i = res.size() - 1;
i >= 0; i--)
{
// If current element is S
if (res[i] + add == start)
index = res.size();
res.push_back(res[i] + add);
}
}
// Check if S is zero
if (start == 0)
return res;
// Rotate the array by index
// value to the left
while (ret.size() < res.size())
{
ret.push_back(res[index]);
index = (index + 1) % res.size();
}
return ret;
}
// Driver Code
int main()
{
int N = 2, S = 3;
vector print = circularPermutation(N, S);
cout << "[";
for(int i = 0; i < print.size() - 1; i++ )
{
cout << print[i] << ", ";
}
cout << print[print.size() - 1] << "]";
return 0;
}
// This code is contributed by susmitakundugoaldanga
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the permutation of
// integers from a given range such that
// number of mismatching bits between
// pairs of adjacent elements is 1
public static List circularPermutation(
int n, int start)
{
// Initialize an arrayList to
// store the resultant permutation
List res = new ArrayList<>(List.of(0)),
ret = new ArrayList<>();
// Store the index of rotation
int index = -1;
// Iterate over the range [0, N - 1]
for (int k = 0, add = 1 << k; k < n;
k++, add = 1 << k) {
// Traverse all the array elements
// up to (2 ^ k)-th index in reverse
for (int i = res.size() - 1;
i >= 0; i--) {
// If current element is S
if (res.get(i) + add == start)
index = res.size();
res.add(res.get(i) + add);
}
}
// Check if S is zero
if (start == 0)
return res;
// Rotate the array by index
// value to the left
while (ret.size() < res.size()) {
ret.add(res.get(index));
index = (index + 1) % res.size();
}
return ret;
}
// Driver Code
public static void main(String[] args)
{
int N = 2, S = 3;
System.out.println(
circularPermutation(N, S));
}
}
Python3
# Python3 program for the above approach
# Function to find the permutation of
# integers from a given range such that
# number of mismatching bits between
# pairs of adjacent elements is 1
def circularPermutation(n, start):
# Initialize an arrayList to
# store the resultant permutation
res = [0]
ret = []
# Store the index of rotation
index, add = -1, 1
# Iterate over the range [0, N - 1]
for k in range(n):
add = 1<
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG
{
// Function to find the permutation of
// integers from a given range such that
// number of mismatching bits between
// pairs of adjacent elements is 1
public static List circularPermutation(
int n, int start)
{
// Initialize an arrayList to
// store the resultant permutation
List res = new List(){0};
List ret = new List();
// Store the index of rotation
int index = -1;
// Iterate over the range [0, N - 1]
for (int k = 0, add = 1 << k; k < n;
k++, add = 1 << k)
{
// Traverse all the array elements
// up to (2 ^ k)-th index in reverse
for (int i = res.Count - 1;
i >= 0; i--)
{
// If current element is S
if (res[i] + add == start)
index = res.Count;
res.Add(res[i] + add);
}
}
// Check if S is zero
if (start == 0)
return res;
// Rotate the array by index
// value to the left
while (ret.Count < res.Count)
{
ret.Add(res[index]);
index = (index + 1) % res.Count;
}
return ret;
}
// Driver Code
static public void Main ()
{
int N = 2, S = 3;
List print = circularPermutation(N, S);
Console.Write("[");
for(int i = 0; i < print.Count - 1; i++ )
{
Console.Write(print[i] + ", ");
}
Console.Write(print[print.Count-1] + "]");
}
}
// This code is contributed by avanitrachhadiya2155
输出:
[3, 2, 0, 1]
时间复杂度: O(N 2 )
辅助空间: O(N)