📜  最小化模运算以使给定的 Array 排列为 [1, N]

📅  最后修改于: 2022-05-13 01:56:05.941000             🧑  作者: Mango

最小化模运算以使给定的 Array 排列为 [1, N]

给定一个大小为N的数组arr[] ,任务是找到使数组成为 [1, N] 范围内数字的排列所需的最小操作次数,其中,在每个操作中,任何索引i处的元素都可以是替换为arr[i]%k (k = 任何大于 0 的值)。如果数组不能成为范围[1, N]中数字的排列,则返回-1

例子:

方法:根据以下观察可以解决问题。

按照下面提到的步骤来实施该方法:

  • 对数组进行排序。
  • 如果1 ≤ arr[i] ≤ N并且它是值为 arr[i] 的元素的第一次出现,则将其保留在那里。
  • 否则,令结果排列中当前最少未赋值的值为 x:
    • 如果x < arr[i]/2 ,则将当前元素赋值给 x 并将操作数加 1。
    • 否则,直接输出-1。

下面是上述方法的实现。

C++
// C++ code to implement above approach
#include 
using namespace std;
 
// Function to find minimum operations
// used to make permutation of 1 to N
void minoperation(vector arr, int N)
{
    set st;
    vector rem;
     
    // Storing one instance of every element
    // from 1 to N
    for (int i = 1; i <= N; i++) {
        st.insert(i);
    }
 
    for (int i = 0; i < N; i++) {
        if (st.find(arr[i]) != st.end())
            st.erase(arr[i]);
        else
            rem.push_back(arr[i]);
    }
     
    // Sorting in descending order
    sort(rem.begin(), rem.end());
    reverse(rem.begin(), rem.end());
 
    int pt = 0;
    bool flag = false;
 
    for (auto& x : rem) {
        auto it = st.end();
        it--;
        int p = (*it);
        if (p > (x - 1) / 2) {
            flag = true;
            break;
        }
        st.erase(it);
    }
 
    if (flag) {
        // Not possible to make permutation.
        cout << "-1";
    }
    else {
        // Minimum number of operation required.
        cout << rem.size();
    }
}
 
// Driver code
int main()
{
    int N = 3;
    vector arr = { 1, 5, 4 };
    minoperation(arr, N);
    return 0;
}


Java
// Java code to implement above approach
import java.util.*;
class GFG{
 
  // Function to find minimum operations
  // used to make permutation of 1 to N
  static void minoperation(int[] arr, int N)
  {
    HashSet st = new HashSet();
    Vector rem = new Vector();
 
    // Storing one instance of every element
    // from 1 to N
    for (int i = 1; i <= N; i++) {
      st.add(i);
    }
 
    for (int i = 0; i < N; i++) {
      if (st.contains(arr[i]))
        st.remove(arr[i]);
      else
        rem.add(arr[i]);
    }
 
    // Sorting in descending order
    Collections.sort(rem,Collections.reverseOrder());
 
    boolean flag = false;
 
    for (int x : rem) {
      int it = st.size();
      it--;
      int p = new ArrayList<>(st).get(it);
      if (p > (x - 1) / 2) {
        flag = true;
        break;
      }
      st.remove(it);
    }
 
    if (flag) {
      // Not possible to make permutation.
      System.out.print("-1");
    }
    else {
      // Minimum number of operation required.
      System.out.print(rem.size());
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int N = 3;
    int[] arr = { 1, 5, 4 };
    minoperation(arr, N);
  }
}
 
// This code is contributed by 29AjayKumar


C#
// C# code to implement above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function to find minimum operations
  // used to make permutation of 1 to N
  static void minoperation(int[] arr, int N)
  {
    HashSet st = new HashSet();
    List rem = new List();
 
    // Storing one instance of every element
    // from 1 to N
    for (int i = 1; i <= N; i++)
    {
      st.Add(i);
    }
 
    for (int i = 0; i < N; i++)
    {
      if (st.Contains(arr[i]))
        st.Remove(arr[i]);
      else
        rem.Add(arr[i]);
    }
 
    // Sorting in descending order
    rem.Sort();
    rem.Reverse();
 
    bool flag = false;
 
    foreach (int x in rem)
    {
      int it = st.Count;
      it--;
      int p = new List(st)[it];
      if (p > (x - 1) / 2)
      {
        flag = true;
        break;
      }
      st.Remove(it);
    }
 
    if (flag)
    {
       
      // Not possible to make permutation.
      Console.Write("-1");
    }
    else
    {
       
      // Minimum number of operation required.
      Console.Write(rem.Count);
    }
  }
 
  // Driver code
  public static void Main()
  {
    int N = 3;
    int[] arr = { 1, 5, 4 };
    minoperation(arr, N);
  }
}
 
// This code is contributed by Saurabh jaiswal


Python3
# Python 3 code to implement above approach
 
# Function to find minimum operations
# used to make permutation of 1 to N
def minoperation(arr, N):
    st = set([])
    rem = []
 
    # Storing one instance of every element
    # from 1 to N
    for i in range(1, N + 1):
        st.add(i)
 
    for i in range(N):
        if (arr[i] in st):
            st.remove(arr[i])
 
        else:
            rem.append(arr[i])
 
    # Sorting in descending order
    rem.sort()
    rem.reverse()
 
    pt = 0
    flag = False
 
    for x in rem:
        it = len(st)
        it -= 1
        p = list(st)[it]
        if (p > (x - 1) / 2):
            flag = True
            break
 
        st.remove(it)
 
    if (flag):
        # Not possible to make permutation.
        print("-1")
 
    else:
        # Minimum number of operation required.
        print(len(rem))
 
# Driver code
if __name__ == "__main__":
 
    N = 3
    arr = [1, 5, 4]
    minoperation(arr, N)
 
    # This code is contributed by ukasp.


Javascript



输出
-1

时间复杂度: O(N * logN)
辅助空间: 在)