📌  相关文章
📜  生成前 N 个自然数的排列,其唯一相邻差的计数等于 K |设置 2

📅  最后修改于: 2022-05-13 01:56:08.507000             🧑  作者: Mango

生成前 N 个自然数的排列,其唯一相邻差的计数等于 K |设置 2

给定两个正整数NK ,任务是构造前N个自然数的排列,使得相邻元素之间所有可能的绝对差为K

例子:

这里已经讨论了这个问题的朴素方法和两指针方法。本文讨论了一种不同的方法双端队列。

方法:很容易看出,可以生成[1, N-1]之间的所有K值的答案。对于此范围之外的任何K ,都不存在答案。为了解决这个问题,为所有当前元素维护一个双端队列和一个存储序列的向量。此外,保持一个布尔值,这将有助于确定弹出前或后元素。迭代剩余的元素,如果K大于1则根据布尔值推送元素并将K减少1 。翻转布尔值,使所有剩余的差值都为1 。请按照以下步骤解决问题:

  • 如果K大于等于N或小于1,则打印-1并返回,因为不存在这样的序列。
  • 初始化一个双端队列dq[]以保持元素的顺序。
  • 使用变量i遍历范围[2, N]并将i推入 deque dq[]的后面
  • 将布尔变量front初始化为true。
  • 初始化一个向量ans[]以存储答案并将1压入向量ans[]。
  • 如果K大于1,则从K中减去1 ,并将front的值与1 异或。
  • 使用变量i遍历范围[2, N]并检查:
    • 如果前面1 ,则弹出 deque dq[]的前面并将其推入向量ans[]否则,将 deque dq[]的后面弹出并将其推入向量ans[] 。此外,如果K大于 then,则从K中减去1 ,然后将front的值与1 异或。
  • 遍历数组ans[]并打印其元素。

下面是上述方法的实现。

C++
// C++ Program for the above approach
#include 
using namespace std;
 
// Function to calculate the required array
void K_ValuesArray(int N, int K)
{
 
    // Check for base cases
    if (K < 1 || K >= N) {
        cout << -1;
        return;
    }
 
    // Maintain a deque to store the
    // elements from [1, N];
    deque dq;
    for (int i = 2; i <= N; i++) {
        dq.push_back(i);
    }
 
    // Maintain a boolean value which will
    // tell from where to pop the element
    bool front = true;
 
    // Create a vector to store the answer
    vector ans;
 
    // Push 1 in the answer initially
    ans.push_back(1);
 
    // Push the remaining elements
    if (K > 1) {
        front ^= 1;
        K--;
    }
 
    // Iterate over the range
    for (int i = 2; i <= N; i++) {
        if (front) {
            int val = dq.front();
            dq.pop_front();
 
            // Push this value in
            // the ans vector
            ans.push_back(val);
            if (K > 1) {
                K--;
 
                // Flip the boolean
                // value
                front ^= 1;
            }
        }
        else {
            int val = dq.back();
            dq.pop_back();
 
            // Push value in ans vector
            ans.push_back(val);
            if (K > 1) {
                K--;
 
                // Flip boolean value
                front ^= 1;
            }
        }
    }
 
    // Print Answer
    for (int i = 0; i < N; i++) {
        cout << ans[i] << " ";
    }
}
 
// Driver Code
int main()
{
    int N = 7, K = 1;
    K_ValuesArray(N, K);
 
    return 0;
}


Java
// Java Program for the above approach
import java.util.*;
class GFG{
 
// Function to calculate the required array
static void K_ValuesArray(int N, int K)
{
 
    // Check for base cases
    if (K < 1 || K >= N) {
        System.out.print(-1);
        return;
    }
 
    // Maintain a deque to store the
    // elements from [1, N];
    Deque dq = new LinkedList();
    for (int i = 2; i <= N; i++) {
        dq.add(i);
    }
 
    // Maintain a boolean value which will
    // tell from where to pop the element
    boolean front = true;
 
    // Create a vector to store the answer
    Vector ans = new Vector();
 
    // Push 1 in the answer initially
    ans.add(1);
 
    // Push the remaining elements
    if (K > 1) {
        front ^=true;
        K--;
    }
 
    // Iterate over the range
    for (int i = 2; i <= N; i++) {
        if (front) {
            int val = dq.peek();
            dq.removeFirst();
 
            // Push this value in
            // the ans vector
            ans.add(val);
            if (K > 1) {
                K--;
 
                // Flip the boolean
                // value
                front ^=true;
            }
        }
        else {
            int val = dq.getLast();
            dq.removeLast();
 
            // Push value in ans vector
            ans.add(val);
            if (K > 1) {
                K--;
 
                // Flip boolean value
                front ^=true;
            }
        }
    }
 
    // Print Answer
    for (int i = 0; i < N; i++) {
        System.out.print(ans.get(i)+ " ");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 7, K = 1;
    K_ValuesArray(N, K);
 
}
}
 
// This code is contributed by 29AjayKumar


Python3
# python Program for the above approach
from collections import deque
 
# Function to calculate the required array
def K_ValuesArray(N, K):
 
    # Check for base cases
    if (K < 1 or K >= N):
        print("-1")
        return
 
    # Maintain a deque to store the
    # elements from [1, N];
    dq = deque()
    for i in range(2, N + 1):
        dq.append(i)
 
    # Maintain a boolean value which will
    # tell from where to pop the element
    front = True
 
    # Create a vector to store the answer
    ans = []
 
    # Push 1 in the answer initially
    ans.append(1)
 
    # Push the remaining elements
    if (K > 1):
        front ^= 1
        K -= 1
 
    # Iterate over the range
    for i in range(2, N+1):
        if (front):
            val = dq.popleft()
 
            # Push this value in
            # the ans vector
            ans.append(val)
            if (K > 1):
                K -= 1
 
                # Flip the boolean
                # value
                front ^= 1
 
        else:
            val = dq.pop()
 
            # Push value in ans vector
            ans.append(val)
            if (K > 1):
                K -= 1
 
                # Flip boolean value
                front ^= 1
 
    # Print Answer
    for i in range(0, N):
        print(ans[i], end=" ")
 
# Driver Code
if __name__ == "__main__":
 
    N = 7
    K = 1
    K_ValuesArray(N, K)
 
    # This code is contributed by rakeshsahni


C#
// C# Program for the above approach
 
using System;
using System.Collections.Generic;
class GFG
{
 
    // Function to calculate the required array
    static void K_ValuesArray(int N, int K)
    {
 
        // Check for base cases
        if (K < 1 || K >= N)
        {
            Console.Write(-1);
            return;
        }
 
        // Maintain a deque to store the
        // elements from [1, N];
        LinkedList dq = new LinkedList();
        for (int i = 2; i <= N; i++)
        {
            dq.AddLast(i);
        }
 
        // Maintain a boolean value which will
        // tell from where to pop the element
        bool front = true;
 
        // Create a vector to store the answer
        List ans = new List();
 
        // Push 1 in the answer initially
        ans.Add(1);
 
        // Push the remaining elements
        if (K > 1)
        {
            front ^= true;
            K--;
        }
 
        // Iterate over the range
        for (int i = 2; i <= N; i++)
        {
            if (front)
            {
                int val = dq.First.Value;
                dq.RemoveFirst();
 
                // Push this value in
                // the ans vector
                ans.Add(val);
                if (K > 1)
                {
                    K--;
 
                    // Flip the boolean
                    // value
                    front ^= true;
                }
            }
            else
            {
                int val = dq.Last.Value;
                dq.RemoveLast();
 
                // Push value in ans vector
                ans.Add(val);
                if (K > 1)
                {
                    K--;
 
                    // Flip boolean value
                    front ^= true;
                }
            }
        }
 
        // Print Answer
        for (int i = 0; i < N; i++)
        {
            Console.Write(ans[i] + " ");
        }
    }
 
    // Driver Code
    public static void Main()
    {
        int N = 7, K = 1;
        K_ValuesArray(N, K);
 
    }
}
 
// This code is contributed by Saurabh Jaiswal


Javascript


输出
1 2 3 4 5 6 7 

时间复杂度: O(N)
辅助空间: O(N)