给定一个数组freq [] ,该数组存储从0到N – 1的N个整数的频率。我们的任务是构造一个序列,使数字i出现次数为freq [i]次数(0≤i≤N – 1),以使两个相邻数字之间的绝对差为1。如果无法生成任何序列,请打印– 1 。
例子:
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.
方法:序列可以从0到N – 1之间的任意数字开始。想法是考虑所有可能的起始元素,即0到N – 1 。选择元素后,我们尝试构建序列。步骤如下:
- 创建一个映射M来存储数字的频率。另外,在变量total中找到频率的总和。
- 在地图中进行迭代,并对地图中的每个元素执行以下操作:
- 创建地图M的副本。
- 创建一个存储可能答案的向量序列。如果当前元素的频率不为零,则递减其频率并将其推入序列中,并尝试通过以下方式形成序列中总共1个元素的其余部分:
- 让我们将插入序列中的最后一个元素称为last 。如果last – 1的频率不为零,则减小其频率并将其推入序列。更新最后一个元素。
- 否则,如果last + 1的频率不为零,则减小其频率并将其推入序列。更新最后一个元素。
- 否则,请从内部循环中断开。
- 如果序列的大小等于总数,则将其作为答案返回。
- 如果找不到这样的序列,则只需返回一个空序列。
下面是上述方法的实现:
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是数组的累积和。