给定两个正整数K和N ,任务是找到所有排列的中间存在的排列,最多为N ,由范围 [1, K] 中的整数组成,按字典顺序排列。
例子:
Input: K = 3, N = 2
Output: 2 1
Explanation: Lexicographical order of all possible permutations are:
- {1}.
- {1, 1}
- {1, 2}
- {1, 3}
- {2}
- {2, 1}
- {2, 2}
- {2, 3}
- {3}
- {3, 1}
- {3, 2}
- {3, 3}
Therefore, the middle lexicographically the smallest sequence is (N/2)th(= 6th) sequence, which is {2, 1}.
Input: K = 2, N = 4
Output: 1 2 2 2
朴素方法:解决给定问题的最简单方法是生成长度为[1, N] 的所有可能子序列,由[1, K] 中的整数组成。将这些元素存储在一个数组中。生成所有子序列后,对存储的子序列列表进行排序并打印列表的中间元素。
时间复杂度: O(N K )
辅助空间: O(N K )
有效的方法:上述方法可以通过检查K的奇偶校验K是奇数还是偶数,然后相应地找到字典序中的最小序列来优化上述方法。请按照以下步骤解决问题:
- 如果K 的值为偶数,则正好有一半的序列以整数K/2或更少开始。因此,结果序列是K/2后跟(N – 1)次出现K 。
- 如果值K为奇数,则将B视为包含(K + 1)/2次出现N次的序列。
- 对于序列X,令f(X)是这样的,X i的X置换为(K + 1 – X I)的序列。
- 唯一的例外是B 的前缀。
- 从序列B开始,并执行以下步骤(N – 1)/2次:
- 如果当前序列的最后一个元素是1 ,则将其删除。
- 否则,将最后一个元素减1 ,当序列包含少于N 个元素时,在序列B的末尾插入K 。
- 完成上述步骤后,打印数组B[] 中得到的序列。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that finds the middle the
// lexicographical smallest sequence
void lexiMiddleSmallest(int K, int N)
{
// If K is even
if (K % 2 == 0) {
// First element is K/2
cout << K / 2 << " ";
// Remamining elements of the
// sequence are all integer K
for (int i = 0; i < N - 1; ++i) {
cout << K << " ";
}
cout << "\n";
exit(0);
}
// Stores the sequence when K
// is odd
vector a(N, (K + 1) / 2);
// Iterate over the range [0, N/2]
for (int i = 0; i < N / 2; ++i) {
// Check if the sequence ends
// with in 1 or not
if (a.back() == 1) {
// Remove the sequence
// ending in 1
a.pop_back();
}
// If it doesn't end in 1
else {
// Decrement by 1
--a.back();
// Insert K to the sequence
// till its size is N
while ((int)a.size() < N) {
a.push_back(K);
}
}
}
// Print the sequence stored
// in the vector
for (auto i : a) {
cout << i << " ";
}
cout << "\n";
}
// Driver Code
int main()
{
int K = 2, N = 4;
lexiMiddleSmallest(K, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function that finds the middle the
// lexicographical smallest sequence
static void lexiMiddleSmallest(int K, int N)
{
// If K is even
if (K % 2 == 0) {
// First element is K/2
System.out.print(K / 2 + " ");
// Remamining elements of the
// sequence are all integer K
for (int i = 0; i < N - 1; ++i) {
System.out.print(K + " ");
}
System.out.println();
return;
}
// Stores the sequence when K
// is odd
ArrayList a = new ArrayList();
// Iterate over the range [0, N/2]
for (int i = 0; i < N / 2; ++i) {
// Check if the sequence ends
// with in 1 or not
if (a.get(a.size() - 1) == 1) {
// Remove the sequence
// ending in 1
a.remove(a.size() - 1);
}
// If it doesn't end in 1
else {
// Decrement by 1
int t = a.get(a.size() - 1) - 1;
a.set(a.get(a.size() - 1), t);
// Insert K to the sequence
// till its size is N
while (a.size() < N) {
a.add(K);
}
}
}
// Print the sequence stored
// in the vector
for (int i : a) {
System.out.print(i + " ");
}
System.out.println();
}
// Driver Code
public static void main(String[] args)
{
int K = 2, N = 4;
lexiMiddleSmallest(K, N);
}
}
// This code is contributed by Dharanendra L V.
Python3
# Python3 program for the above approach
# Function that finds the middle the
# lexicographical smallest sequence
def lexiMiddleSmallest(K, N):
# If K is even
if (K % 2 == 0):
# First element is K/2
print(K // 2,end=" ")
# Remamining elements of the
# sequence are all integer K
for i in range(N - 1):
print(K, end = " ")
print()
return
# Stores the sequence when K
# is odd
a = [(K + 1) // 2]*(N)
# Iterate over the range [0, N/2]
for i in range(N//2):
# Check if the sequence ends
# with in 1 or not
if (a[-1] == 1):
# Remove the sequence
# ending in 1
del a[-1]
# If it doesn't end in 1
else:
# Decrement by 1
a[-1] -= 1
# Insert K to the sequence
# till its size is N
while (len(a) < N):
a.append(K)
# Prthe sequence stored
# in the vector
for i in a:
print(i, end = " ")
print()
# Driver Code
if __name__ == '__main__':
K, N = 2, 4
lexiMiddleSmallest(K, N)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function that finds the middle the
// lexicographical smallest sequence
static void lexiMiddleSmallest(int K, int N)
{
// If K is even
if (K % 2 == 0) {
// First element is K/2
Console.Write(K / 2 + " ");
// Remamining elements of the
// sequence are all integer K
for (int i = 0; i < N - 1; ++i) {
Console.Write(K + " ");
}
Console.WriteLine();
return;
}
// Stores the sequence when K
// is odd
List a = new List();
// Iterate over the range [0, N/2]
for (int i = 0; i < N / 2; ++i) {
// Check if the sequence ends
// with in 1 or not
if (a[a.Count - 1] == 1) {
// Remove the sequence
// ending in 1
a.Remove(a.Count - 1);
}
// If it doesn't end in 1
else {
// Decrement by 1
a[a.Count - 1] -= 1;
// Insert K to the sequence
// till its size is N
while ((int)a.Count < N) {
a.Add(K);
}
}
}
// Print the sequence stored
// in the vector
foreach(int i in a) { Console.Write(i + " "); }
Console.WriteLine();
}
// Driver Code
public static void Main()
{
int K = 2, N = 4;
lexiMiddleSmallest(K, N);
}
}
// This code is contributed by ukasp.
Javascript
输出:
1 2 2 2
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。