📜  排列出现在最长 N 的排列的字典序排列中间,由最大 K 的整数组成

📅  最后修改于: 2021-10-25 09:24:28             🧑  作者: Mango

给定两个正整数KN ,任务是找到所有排列的中间存在的排列,最多为N ,由范围 [1, K] 中的整数组成,按字典顺序排列。

例子:

朴素方法:解决给定问题的最简单方法是生成长度为[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 iX置换为(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 现场工作专业课程学生竞争性编程现场课程