📌  相关文章
📜  找到可以通过重新排列第二个数组的元素形成的字典序最小序列

📅  最后修改于: 2021-10-27 09:13:32             🧑  作者: Mango

给定两个由N 个整数组成的数组AB。将 B 的元素本身重新排序,使得重新排序后由(A[i] + B[i]) % N形成的序列在字典序上是最小的。任务是打印尽可能按字典顺序排列的最小序列。
注意:数组元素在 [0, n) 范围内。
例子:

解决办法:贪心即可解决问题。最初使用散列对数组B的所有数字进行计数,并将它们存储在C++中的集合中,以便lower_bound() [检查元素]和erase() [擦除元素]操作可以在对数时间。
对于数组中的每个元素,使用lower_bound函数检查等于或大于na[i] 的数字。如果没有这样的元素,则取集合中最小的元素。将哈希表中使用的数字的值减 1,如果哈希表的值为 0,则也从集合中删除该元素。
但是有一个例外,如果数组元素为 0,则首先检查 0 然后检查 N,如果它们都不存在,则取最小的元素。
下面是上述方法的实现:

CPP
// 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 appears, 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