Construct a sequence from given frequencies of N consecutive integers with unit adjacent difference

Given an array freq[] which stores the frequency of N integers from 0 to N – 1. The task is to construct a sequence where number i appears freq[i] number of times (0 ≤ i ≤ N – 1) such that the absolute difference between two adjacent numbers is 1. If it’s not possible to generate any sequence then print -1.

Examples:

Input: freq[] = {2, 2, 2, 3, 1}
Output: 0 1 0 1 2 3 2 3 4 3
Explanation:
The absolute difference between the adjacent numbers in the above sequence is always 1.

Input: freq[] = {1, 2, 3}
Output: -1
Explanation:
There cannot be any sequence whose absolute difference will always be one.

Approach: The sequence can start from any number between 0 and N – 1. The idea is to consider all possibilities for starting element namely 0 to N – 1. After choosing the element, we try to construct the sequence. Below are the steps:



  1. Create a map M to store the frequency of numbers. Also find the sum of frequencies in a variable say total.
  2. Iterate in the map and do the following for each element in the map:
    • Create a copy of the map M.
    • Create a vector sequence which stores the possible answer. If the frequency of current element is non zero then decrement its frequency and push it into sequence and try to form the rest of the total – 1 elements of the sequence in the following way:
      1. Let us call the last element inserted in the sequence as last. If the frequency of last – 1 is non zero, then decrement its frequency and push it into the sequence. Update the last element.
      2. Otherwise if the frequency of last + 1 is non zero, then decrement its frequency and push it into the sequence. Update the last element.
      3. Otherwise break from the inner loop.
    • If the size of sequence is equal to total then return it as answer.
    • If no such sequence is found, then just return an empty sequence.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Funtion generates the sequence
vector<int> generateSequence(int* freq,
                             int n)
{
    // Map to store the frequency
    // of numebrs
    map<int, int> 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<int> 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<int> 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<int> 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;
}

chevron_right


Output:

0 1 0 1 2 3 2 3 4 3

Time Complexity: O(N * total), where N is the size of the array, and total is the cumulative sum of the array.
Auxiliary Space: O(total), where total is the cumulative sum of the array.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.