给定两个整数n和k。考虑自然n个数的第一个排列,P =“ 1 2 3…n”,打印排列“结果”,使得abs(Result i – P i )= k ,其中P i表示i在排列P中的位置。 P i的范围从1到n。如果有多个可能的结果,则打印按字典顺序最小的结果。
Input: n = 6 k = 3
Output: 4 5 6 1 2 3
Explanation:
P = 1 2 3 4 5 6
Result = 4 5 6 1 2 3
We can notice that the difference between
individual numbers (at same positions) of
P and result is 3 and "4 5 6 1 2 3" is
lexicographically smallest such permutation.
Other greater permutations could be
Input : n = 6 k = 2
Output : Not possible
Explanation: No permutation is possible
with difference is k
天真的方法是生成从1到n的所有置换,并选择满足绝对差k的最小置换。此方法的时间复杂度为Ω(n!),对于较大的n值,肯定会超时。
高效的方法是观察索引每个位置的模式。对于索引i的每个位置,只能存在两个候选项,即i + k和i – k。由于我们需要找到按字典顺序排列的最小排列,因此我们将首先寻找i-k个候选(如果可能),然后寻找i + k个候选。
Illustration:
n = 8, k = 2
P : 1 2 3 4 5 6 7 8
For any ith position we will check which candidate
is possible i.e., i + k or i - k
1st pos = 1 + 2 = 3 (1 - 2 not possible)
2nd pos = 2 + 2 = 4 (2 - 2 not possible)
3rd pos = 3 - 2 = 1 (possible)
4th pos = 4 - 2 = 2 (possible)
5th pos = 5 + 2 = 7 (5 - 2 already placed, not possible)
6th pos = 6 + 2 = 8 (6 - 2 already placed, not possible)
7th pos = 7 - 2 = 5 (possible)
8th pos = 8 - 2 = 6 (possible)
注意:如果我们观察上面的插图,我们将发现在第k个连续间隔之后,i + k和i – k交替出现。另一个观察结果是,整个排列仅在n为偶数时才能将n分为两部分,其中每个部分必须可被k整除。
C++
// C++ program to find k absolute difference
// permutation
#include
using namespace std;
void kDifferencePermutation(int n, int k)
{
// If k is 0 then we just print the
// permutation from 1 to n
if (!k)
{
for (int i = 0; i < n; ++i)
cout << i + 1 << " ";
}
// Check whether permutation is feasible or not
else if (n % (2 * k) != 0)
cout <<"Not Possible";
else
{
for (int i = 0; i < n; ++i)
{
// Put i + k + 1 candidate if position is
// feasible, otherwise put the i - k - 1
// candidate
if ((i / k) % 2 == 0)
cout << i + k + 1 << " ";
else
cout << i - k + 1 << " ";
}
}
cout << "\n";
}
// Driver code
int main()
{
int n = 6 , k = 3;
kDifferencePermutation(n, k);
n = 6 , k = 2;
kDifferencePermutation(n, k);
n = 8 , k = 2;
kDifferencePermutation(n, k);
return 0;
}
Java
// Java program to find k absolute
// difference permutation
import java.io.*;
class GFG {
static void kDifferencePermutation(int n,
int k)
{
// If k is 0 then we just print the
// permutation from 1 to n
if (!(k > 0))
{
for (int i = 0; i < n; ++i)
System.out.print( i + 1 + " ");
}
// Check whether permutation is
// feasible or not
else if (n % (2 * k) != 0)
System.out.print("Not Possible");
else
{
for (int i = 0; i < n; ++i)
{
// Put i + k + 1 candidate
// if position is feasible,
// otherwise put the
// i - k - 1 candidate
if ((i / k) % 2 == 0)
System.out.print( i + k
+ 1 + " ");
else
System.out.print( i - k
+ 1 + " ");
}
}
System.out.println() ;
}
// Driver code
static public void main (String[] args)
{
int n = 6 , k = 3;
kDifferencePermutation(n, k);
n = 6 ;
k = 2;
kDifferencePermutation(n, k);
n = 8 ;
k = 2;
kDifferencePermutation(n, k);
}
}
// This code is contributed by anuj_67.
Python3
# Python 3 program to find k
# absolute difference permutation
def kDifferencePermutation(n, k):
# If k is 0 then we just print the
# permutation from 1 to n
if (k == 0):
for i in range(n):
print(i + 1, end = " ")
# Check whether permutation
# is feasible or not
elif (n % (2 * k) != 0):
print("Not Possible", end = "")
else:
for i in range(n):
# Put i + k + 1 candidate if position is
# feasible, otherwise put the i - k - 1
# candidate
if (int(i / k) % 2 == 0):
print(i + k + 1, end = " ")
else:
print(i - k + 1, end = " ")
print("\n", end = "")
# Driver code
if __name__ == '__main__':
n = 6
k = 3
kDifferencePermutation(n, k)
n = 6
k = 2
kDifferencePermutation(n, k)
n = 8
k = 2
kDifferencePermutation(n, k)
# This code is contributed by
# Surendra_Gangwar
C#
// C# program to find k absolute
// difference permutation
using System;
class GFG {
static void kDifferencePermutation(int n,
int k)
{
// If k is 0 then we just print the
// permutation from 1 to n
if (!(k > 0))
{
for (int i = 0; i < n; ++i)
Console.Write( i + 1 + " ");
}
// Check whether permutation is
// feasible or not
else if (n % (2 * k) != 0)
Console.Write("Not Possible");
else
{
for (int i = 0; i < n; ++i)
{
// Put i + k + 1 candidate
// if position is feasible,
// otherwise put the
// i - k - 1 candidate
if ((i / k) % 2 == 0)
Console.Write( i + k
+ 1 + " ");
else
Console.Write( i - k
+ 1 + " ");
}
}
Console.WriteLine() ;
}
// Driver code
static public void Main ()
{
int n = 6 , k = 3;
kDifferencePermutation(n, k);
n = 6 ;
k = 2;
kDifferencePermutation(n, k);
n = 8 ;
k = 2;
kDifferencePermutation(n, k);
}
}
// This code is contributed by anuj_67.
PHP
输出:
4 5 6 1 2 3
Not Possible
3 4 1 2 7 8 5 6
时间复杂度: O(n)
辅助空间: O(1)