📌  相关文章
📜  从N个连续整数的给定频率构造一个序列,单位相邻差

📅  最后修改于: 2021-04-25 01:06:56             🧑  作者: Mango

给定一个数组freq [] ,该数组存储从0到N – 1N个整数的频率。我们的任务是构造一个序列,使数字i出现次数为freq [i]次数(0≤i≤N – 1),以使两个相邻数字之间的绝对差为1。如果无法生成任何序列,请打印– 1

例子:

方法:序列可以从0到N – 1之间的任意数字开始。想法是考虑所有可能的起始元素,即0到N – 1 。选择元素后,我们尝试构建序列。步骤如下:

  1. 创建一个映射M来存储数字的频率。另外,在变量total中找到频率的总和。
  2. 在地图中进行迭代,并对地图中的每个元素执行以下操作:
    • 创建地图M的副本。
    • 创建一个存储可能答案的向量序列。如果当前元素的频率不为零,则递减其频率并将其推入序列中,并尝试通过以下方式形成序列中总共1个元素的其余部分:
      1. 让我们将插入序列中的最后一个元素称为last 。如果last – 1的频率不为零,则减小其频率并将其推入序列。更新最后一个元素。
      2. 否则,如果last + 1的频率不为零,则减小其频率并将其推入序列。更新最后一个元素。
      3. 否则,请从内部循环中断开。
    • 如果序列的大小等于总数,则将其作为答案返回。
    • 如果找不到这样的序列,则只需返回一个空序列。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Funtion generates the sequence
vector generateSequence(int* freq,
                             int n)
{
    // Map to store the frequency
    // of numebrs
    map m;
 
    // Sum of all frequencies
    int total = 0;
 
    for (int i = 0; i < n; i++) {
        m[i] = freq[i];
 
        total += freq[i];
    }
 
    // Try all possibilities
    // for the starting element
    for (int i = 0; i < n; i++) {
 
        // If the frequency of current
        // element is non-zero
        if (m[i]) {
 
            // vector to store the answer
            vector sequence;
 
            // Copy of the map for every
            // possible starting element
            auto mcopy = m;
 
            // Decrement the frequency
            mcopy[i]--;
 
            // Push the starting element
            // to the vector
            sequence.push_back(i);
 
            // The last element inserted
            // is i
            int last = i;
 
            // Try to fill the rest of
            // the positions if possible
            for (int i = 0;
                 i < total - 1; i++) {
 
                // If the frequency of last - 1
                // is non-zero
 
                if (mcopy[last - 1]) {
 
                    // Decrement the frequency
                    // of last - 1
                    mcopy[last - 1]--;
 
                    // Insert  it into the
                    // sequence
                    sequence.push_back(last - 1);
 
                    // Update last number
                    // added to sequence
                    last--;
                }
 
                else if (mcopy[last + 1]) {
                    mcopy[last + 1]--;
                    sequence.push_back(last + 1);
                    last++;
                }
 
                // Break from the inner loop
                else
                    break;
            }
 
            // If the size of the sequence
            // vector is equal to sum of
            // total frequqncies
            if (sequence.size() == total) {
 
                // Return sequence
                return sequence;
            }
        }
    }
 
    vector empty;
 
    // If no such sequence if found
    // return empty sequence
    return empty;
}
 
// Function Call to print the sequence
void PrintSequence(int freq[], int n)
{
    // The required sequence
    vector sequence
        = generateSequence(freq, n);
 
    // If the size of sequecne
    // if zero it means no such
    // sequence was found
    if (sequence.size() == 0) {
        cout << "-1";
    }
 
    // Otherwise print the sequence
    else {
 
        for (int i = 0;
             i < sequence.size(); i++) {
            cout << sequence[i] << " ";
        }
    }
}
 
// Driver Code
int main()
{
    // Frequency of all elements
    // from 0 to n-1
    int freq[] = { 2, 2, 2, 3, 1 };
 
    // Number of elements whose
    // frequencies are given
    int N = 5;
 
    // Function Call
    PrintSequence(freq, N);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Funtion generates the sequence
static Vector generateSequence(int []freq,
                                        int n)
{
     
    // Map to store the frequency
    // of numebrs
    HashMap m = new HashMap();
 
    // Sum of all frequencies
    int total = 0;
 
    for(int i = 0; i < n; i++)
    {
        m.put(i, freq[i]);
        total += freq[i];
    }
 
    // Try all possibilities
    // for the starting element
    for(int i = 0; i < n; i++)
    {
         
        // If the frequency of current
        // element is non-zero
        if (m.containsKey(i))
        {
             
            // vector to store the answer
            Vector sequence = new Vector();
 
            // Copy of the map for every
            // possible starting element
            @SuppressWarnings("unchecked")
            HashMap mcopy = (HashMap) m.clone();
 
            // Decrement the frequency
            if (mcopy.containsKey(i) && mcopy.get(i) > 0)
                mcopy.put(i, mcopy.get(i) - 1);
 
            // Push the starting element
            // to the vector
            sequence.add(i);
 
            // The last element inserted
            // is i
            int last = i;
 
            // Try to fill the rest of
            // the positions if possible
            for(int i1 = 0; i1 < total - 1; i1++)
            {
                 
                // If the frequency of last - 1
                // is non-zero
                if (mcopy.containsKey(last - 1) &&
                            mcopy.get(last - 1) > 0)
                {
                     
                    // Decrement the frequency
                    // of last - 1
                    mcopy.put(last - 1,
                    mcopy.get(last - 1) - 1);
 
                    // Insert  it into the
                    // sequence
                    sequence.add(last - 1);
 
                    // Update last number
                    // added to sequence
                    last--;
                }
 
                else if (mcopy.containsKey(last + 1))
                {
                    mcopy.put(last + 1,
                    mcopy.get(last + 1) - 1);
                    sequence.add(last + 1);
                    last++;
                }
 
                // Break from the inner loop
                else
                    break;
            }
 
            // If the size of the sequence
            // vector is equal to sum of
            // total frequqncies
            if (sequence.size() == total)
            {
                 
                // Return sequence
                return sequence;
            }
        }
    }
 
    Vector empty = new Vector();
 
    // If no such sequence if found
    // return empty sequence
    return empty;
}
 
// Function call to print the sequence
static void PrintSequence(int freq[], int n)
{
     
    // The required sequence
    Vector sequence = generateSequence(freq, n);
 
    // If the size of sequecne
    // if zero it means no such
    // sequence was found
    if (sequence.size() == 0)
    {
        System.out.print("-1");
    }
 
    // Otherwise print the sequence
    else
    {
        for(int i = 0; i < sequence.size(); i++)
        {
            System.out.print(sequence.get(i) + " ");
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Frequency of all elements
    // from 0 to n-1
    int freq[] = { 2, 2, 2, 3, 1 };
 
    // Number of elements whose
    // frequencies are given
    int N = 5;
 
    // Function call
    PrintSequence(freq, N);
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program for the above approach
 
# Funtion generates the sequence
def generateSequence(freq, n):
     
    # Map to store the frequency
    # of numebrs
    m = {}
 
    # Sum of all frequencies
    total = 0
 
    for i in range(n):
        m[i] = freq[i]
        total += freq[i]
 
    # Try all possibilities
    # for the starting element
    for i in range(n):
 
        # If the frequency of current
        # element is non-zero
        if (m[i]):
 
            # vector to store the answer
            sequence = []
 
            # Copy of the map for every
            # possible starting element
            mcopy = {}
 
            for j in m:
                mcopy[j] = m[j]
 
            # Decrement the frequency
            mcopy[i] -= 1
 
            # Push the starting element
            # to the vector
            sequence.append(i)
 
            # The last element inserted
            # is i
            last = i
 
            # Try to fill the rest of
            # the positions if possible
            for j in range(total - 1):
                 
                # If the frequency of last - 1
                # is non-zero
                if ((last - 1) in mcopy and
                   mcopy[last - 1] > 0):
 
                    # Decrement the frequency
                    # of last - 1
                    mcopy[last - 1] -= 1
 
                    # Insert  it into the
                    # sequence
                    sequence.append(last - 1)
 
                    # Update last number
                    # added to sequence
                    last -= 1
 
                elif (mcopy[last + 1]):
                    mcopy[last + 1] -= 1
                    sequence.append(last + 1)
                    last += 1
 
                # Break from the inner loop
                else:
                    break
 
            # If the size of the sequence
            # vector is equal to sum of
            # total frequqncies
            if (len(sequence) == total):
 
                # Return sequence
                return sequence
 
    # If no such sequence if found
    # return empty sequence
    return []
 
# Function Call to print the sequence
def PrintSequence(freq, n):
     
    # The required sequence
    sequence = generateSequence(freq, n)
 
    # If the size of sequecne
    # if zero it means no such
    # sequence was found
    if (len(sequence) == 0):
        print("-1")
 
    # Otherwise print the sequence
    else:
        for i in range(len(sequence)):
            print(sequence[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
     
    # Frequency of all elements
    # from 0 to n-1
    freq = [ 2, 2, 2, 3, 1 ]
 
    # Number of elements whose
    # frequencies are given
    N = 5
 
    # Function Call
    PrintSequence(freq, N)
 
# This code is contributed by mohit kumar 29


C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Funtion generates the sequence
static List generateSequence(int []freq,
                                  int n)
{
  // Map to store the frequency
  // of numebrs
  Dictionary m = new Dictionary();
 
  // Sum of all frequencies
  int total = 0;
 
  for(int i = 0; i < n; i++)
  {
    m.Add(i, freq[i]);
    total += freq[i];
  }
 
  // Try all possibilities
  // for the starting element
  for(int i = 0; i < n; i++)
  {
    // If the frequency of current
    // element is non-zero
    if (m.ContainsKey(i))
    {
      // vector to store the answer
      List sequence = new List();
 
      // Copy of the map for every
      // possible starting element
 
      Dictionary mcopy = new Dictionary(m);
 
      // Decrement the frequency
      if (mcopy.ContainsKey(i) && mcopy[i] > 0)
        mcopy[i] = mcopy[i] - 1;
 
      // Push the starting element
      // to the vector
      sequence.Add(i);
 
      // The last element inserted
      // is i
      int last = i;
 
      // Try to fill the rest of
      // the positions if possible
      for(int i1 = 0; i1 < total - 1; i1++)
      {
        // If the frequency of last - 1
        // is non-zero
        if (mcopy.ContainsKey(last - 1) &&
            mcopy[last - 1] > 0)
        {
          // Decrement the frequency
          // of last - 1
          mcopy[last - 1] = mcopy[last - 1] - 1;
 
          // Insert  it into the
          // sequence
          sequence.Add(last - 1);
 
          // Update last number
          // added to sequence
          last--;
        }
 
        else if (mcopy.ContainsKey(last + 1))
        {
          mcopy[last + 1] = mcopy[last + 1] - 1;
          sequence.Add(last + 1);
          last++;
        }
 
        // Break from the inner loop
        else
          break;
      }
 
      // If the size of the sequence
      // vector is equal to sum of
      // total frequqncies
      if (sequence.Count == total)
      {
        // Return sequence
        return sequence;
      }
    }
  }
 
  List empty = new List();
 
  // If no such sequence if found
  // return empty sequence
  return empty;
}
 
// Function call to print the sequence
static void PrintSequence(int []freq, int n)
{
  // The required sequence
  List sequence = generateSequence(freq, n);
 
  // If the size of sequecne
  // if zero it means no such
  // sequence was found
  if (sequence.Count == 0)
  {
    Console.Write("-1");
  }
 
  // Otherwise print the sequence
  else
  {
    for(int i = 0; i < sequence.Count; i++)
    {
      Console.Write(sequence[i] + " ");
    }
  }
}
 
// Driver Code
public static void Main(String[] args)
{
  // Frequency of all elements
  // from 0 to n-1
  int []freq = {2, 2, 2, 3, 1};
 
  // Number of elements whose
  // frequencies are given
  int N = 5;
 
  // Function call
  PrintSequence(freq, N);
}
}
 
// This code is contributed by Princi Singh


输出:
0 1 0 1 2 3 2 3 4 3

时间复杂度: O(N * total) ,其中N是数组的大小,而total是数组的累加和。
辅助空间: O(total) ,其中total是数组的累积和。