📌  相关文章
📜  按最小字法替换的具有不同元素的按字典顺序排列的最小排列

📅  最后修改于: 2021-06-25 14:09:35             🧑  作者: Mango

给定n个正整数的数组,使得整数的每个元素从1到n。找到可以通过替换数组中最小数量的元素而获得的字典排列,以使数组中的每个元素在整个数组中仅出现一次。首先,打印所需的最少数量的替换,然后打印最终的字典排列。
例子:

Input arr[] = {2, 3, 4, 3, 2}
Output 2
           1 3 4 5 2
Explanation
Replace number '2' at position 1st with number 
'1' and '3' at position 4th with number '5'. 
The array that we obtain is [1, 3, 4, 5, 2]
which is lexicographically smallest among all 
the possible suitable.

Input arr[] = {2, 1, 2, 1, 2}
Output 3
           2 1 3 4 5 

天真的方法是生成从1到n的所有置换,并选择最小的置换。此方法的时间复杂度为O(n!),对于较大的n值,肯定会超时。
高效的方法是贪婪地选择所需的元素。首先初始化cnt []数组,该数组将包含该数组中出现的元素的频率。对于在数组中多次出现的array(a i )的每个元素,由于按字典顺序排列的最小排列,因此按升序添加数字。例如,
遍历所有元素的数组。令当前数组个数为i 。如果i的计数等于1,则移至下一个数组数。如果A I计数大于1则替换的数目的i相元件ELE(其不处于阵列发生最小的数)仅当ELE I。同时,减少cnt []数组中i的数量。
如果ele> a i,则标记数字a i,以便我们可以在下一次迭代中替换它。之所以需要执行此步骤,是因为我们需要对字典进行最小的排列

C++
// C++ program to print lexicographically
// permutation array by replacing minimum
// element of array
#include 
using namespace std;
 
// Function to calculate lexicographically permutation
// in array
void lexicoSmallestPermuatation(int arr[], int n)
{
    // Calculate frequency of array elements
    int cnt[n + 1];
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; ++i)
        ++cnt[arr[i]];
 
    int ele = 1, replacement = 0;
    bool vis[n + 1];
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i < n; ++i) {
 
        // If count of element is 1, no
        // need to replace
        if (cnt[arr[i]] == 1)
            continue;
 
        // Find the element that has not
        // occurred in array
        while (cnt[ele])
            ++ele;
 
        // If replacement element is greater
        // than current arr[i] then visit
        // that element for next iteration
        if (ele > arr[i] && !vis[arr[i]])
            vis[arr[i]] = 1;
 
        else {
 
            // Decrement count and assign the element
            // to array
            --cnt[arr[i]];
            arr[i] = ele;
 
            // Increment the replacement count
            ++replacement;
 
            // Increment element after assigning
            // to the array
            ++ele;
        }
    }
 
    cout << replacement << "\n";
    for (int i = 0; i < n; ++i)
        cout << arr[i] << " ";
}
 
// Driver code
int main()
{
    int arr[] = { 2, 3, 4, 3, 2 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    lexicoSmallestPermuatation(arr, sz);
    return 0;
}


Java
// Java program to print lexicographically
// permutation array by replacing minimum
// element of array
 
class GFG {
 
// Function to calculate lexicographically permutation
// in array
    static void lexicoSmallestPermuatation(int arr[], int n) {
        // Calculate frequency of array elements
        int cnt[] = new int[n + 1];
        for (int i = 0; i < n; ++i) {
            ++cnt[arr[i]];
        }
 
        int ele = 1, replacement = 0;
        boolean vis[] = new boolean[n + 1];
        for (int i = 0; i < n; ++i) {
 
            // If count of element is 1, no
            // need to replace
            if (cnt[arr[i]] == 1) {
                continue;
            }
 
            // Find the element that has not
            // occurred in array
            while (cnt[ele]>0) {
                ++ele;
            }
 
            // If replacement element is greater
            // than current arr[i] then visit
            // that element for next iteration
            if (ele > arr[i] && !vis[arr[i]]) {
                vis[arr[i]] = true;
            } else {
 
                // Decrement count and assign the element
                // to array
                --cnt[arr[i]];
                arr[i] = ele;
 
                // Increment the replacement count
                ++replacement;
 
                // Increment element after assigning
                // to the array
                ++ele;
            }
        }
 
        System.out.print(replacement + "\n");
        for (int i = 0; i < n; ++i) {
            System.out.print(arr[i] + " ");
        }
    }
 
// Driver code
    public static void main(String[] args) {
        int arr[] = {2, 3, 4, 3, 2};
        int sz = arr.length;
        lexicoSmallestPermuatation(arr, sz);
 
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 program to print lexicographically
# permutation array by replacing minimum
# element of array
 
# Function to calculate lexicographically
# permutation in array
def lexicoSmallestPermuatation(arr, n):
     
    # Calculate frequency of array elements
    cnt = [0 for i in range(n + 1)]
    for i in range(n):
        cnt[arr[i]] += 1
 
    ele = 1
    replacement = 0
    vis = [0 for i in range(n + 1)]
    for i in range(n):
         
        # If count of element is 1, no
        # need to replace
        if (cnt[arr[i]] == 1):
            continue
 
        # Find the element that has not
        # occurred in array
        while (cnt[ele]):
            ele += 1
 
        # If replacement element is greater
        # than current arr[i] then visit
        # that element for next iteration
        if (ele > arr[i] and vis[arr[i]] == 0):
            vis[arr[i]] = 1;
 
        else:
             
            # Decrement count and assign
            # the element to array
            cnt[arr[i]] -= 1
            arr[i] = ele
 
            # Increment the replacement count
            replacement += 1
 
            # Increment element after assigning
            # to the array
            ele += 1
     
    print(replacement)
    for i in range(n):
        print(arr[i], end = " ")
 
# Driver code
if __name__ == '__main__':
    arr = [2, 3, 4, 3, 2]
    sz = len(arr)
    lexicoSmallestPermuatation(arr, sz)
     
# This code is contributed by
# Shashank_Sharma


C#
// C# program to print lexicographically
// permutation array by replacing minimum
// element of array 
using System;
public class GFG {
 
// Function to calculate lexicographically permutation
// in array
    static void lexicoSmallestPermuatation(int []arr, int n) {
        // Calculate frequency of array elements
        int []cnt= new int[n + 1];
        for (int i = 0; i < n; ++i) {
            ++cnt[arr[i]];
        }
 
        int ele = 1, replacement = 0;
        bool []vis = new bool[n + 1];
        for (int i = 0; i < n; ++i) {
 
            // If count of element is 1, no
            // need to replace
            if (cnt[arr[i]] == 1) {
                continue;
            }
 
            // Find the element that has not
            // occurred in array
            while (cnt[ele]>0) {
                ++ele;
            }
 
            // If replacement element is greater
            // than current arr[i] then visit
            // that element for next iteration
            if (ele > arr[i] && !vis[arr[i]]) {
                vis[arr[i]] = true;
            } else {
 
                // Decrement count and assign the element
                // to array
                --cnt[arr[i]];
                arr[i] = ele;
 
                // Increment the replacement count
                ++replacement;
 
                // Increment element after assigning
                // to the array
                ++ele;
            }
        }
 
        Console.Write(replacement + "\n");
        for (int i = 0; i < n; ++i) {
            Console.Write(arr[i] + " ");
        }
    }
 
// Driver code
    public static void Main() {
        int []arr = {2, 3, 4, 3, 2};
        int sz = arr.Length;
        lexicoSmallestPermuatation(arr, sz);
 
    }
}
 
// This code is contributed by Rajput-Ji//


PHP
 $arr[$i] && !$vis[$arr[$i]])
            $vis[$arr[$i]] = 1;
 
        else
        {
 
            // Decrement count and assign the
            // element to array
            --$cnt[$arr[$i]];
            $arr[$i] = $ele;
 
            // Increment the replacement count
            ++$replacement;
 
            // Increment element after assigning
            // to the array
            ++$ele;
        }
    }
 
    echo $replacement. "\n";
    for ($i = 0; $i < $n; ++$i)
        echo $arr[$i] . " ";
}
 
// Driver code
$arr = array(2, 3, 4, 3, 2 );
$sz = sizeof($arr);
lexicoSmallestPermuatation($arr, $sz);
 
// This code is contributed by ita_c
?>


Javascript


输出

2
1 3 4 5 2