给定两个由N个整数组成的数组A和B。对B元素本身进行重新排序,以使重新排序后由(A [i] + B [i])%N形成的序列在字典上最小。该任务是打印按字典顺序排列的最小序列。
注意:数组元素的范围为[0,n)。
例子:
Input: a[] = {0, 1, 2, 1}, b[] = {3, 2, 1, 1}
Output: 1 0 0 2
Reorder B to {1, 3, 2, 1} to get the smallest sequence possible.
Input: a[] = {2, 0, 0}, b[] = {1, 0, 2}
Output: 0 0 2
方法:可以贪婪地解决问题。最初使用散列对数组B的所有数字进行计数,并将其存储在C++中的集合中,以便可以在以下位置执行lower_bound()[检查元素]和delete()[擦除元素]操作对数时间。
对于数组中的每个元素,请使用lower_bound函数检查等于或大于na [i]的数字。如果没有这样的元素,则采用集合中最小的元素。将哈希表中使用的数字值减1,如果哈希表的值为0,则还将集合中的元素也删除。
但是,如果数组元素为0,则存在例外,然后首先检查0,然后检查N,如果两者都不存在,则取最小的元素。
下面是上述方法的实现:
// C++ implementation of the
// above approach
#include
using namespace std;
// Function to get the smallest
// sequence possible
void solve(int a[], int b[], int n)
{
// Hash-table to count the
// number of occurrences of b[i]
unordered_map mpp;
// Store the element in sorted order
// for using binary search
set st;
// Iterate in the B array
// and count the occurrences and
// store in the set
for (int i = 0; i < n; i++) {
mpp[b[i]]++;
st.insert(b[i]);
}
vector sequence;
// Iterate for N elements
for (int i = 0; i < n; i++) {
// If the element is 0
if (a[i] == 0) {
// Find the nearest number to 0
auto it = st.lower_bound(0);
int el = *it;
sequence.push_back(el % n);
// Decrease the count
mpp[el]--;
// Erase if no more are there
if (!mpp[el])
st.erase(el);
}
// If the element is other than 0
else {
// Find the difference
int x = n - a[i];
// Find the nearest number which can give us
// 0 on modulo
auto it = st.lower_bound(x);
// If no such number occurs then
// find the number closest to 0
if (it == st.end())
it = st.lower_bound(0);
// Get the number
int el = *it;
// store the number
sequence.push_back((a[i] + el) % n);
// Decrease the count
mpp[el]--;
// If no more appers, then erase it from set
if (!mpp[el])
st.erase(el);
}
}
for (auto it : sequence)
cout << it << " ";
}
// Driver Code
int main()
{
int a[] = { 0, 1, 2, 1 };
int b[] = { 3, 2, 1, 1 };
int n = sizeof(a) / sizeof(a[0]);
solve(a, b, n);
return 0;
}
输出:
1 0 0 2