📌  相关文章
📜  使用循环旋转最大化给定排列中相应相同元素的数量

📅  最后修改于: 2021-05-17 06:13:23             🧑  作者: Mango

给定两个从1到N的数字排列P1P2 ,任务是通过对P1进行循环左移或右移来找到给定排列中相应相同元素的最大计数。
例子:

天真的方法:天真的方法是通过循环形成的所有排列来检查左右方向上的每个可能移位,以计算匹配对的数量。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:可以优化上述幼稚的方法。这个想法是让每个元素在单独的数组中从左侧和右侧存储此元素位置之间的较小距离。因此,该问题的解决方案将被计算为来自两个分开的阵列的元素的最大频率。步骤如下:

  1. 将排列P2的所有元素的位置存储在数组中(例如store [] )。
  2. 对于置换P1中的每个元素,请执行以下操作:
    • 求出当前元素在P2中的位置与P1中的位置之间的差异(例如diff )。
    • 如果diff小于0,则将diff更新为(N – diff)
    • 将电流差diff的频率存储在映射中。
  3. 完成上述步骤后,映射中存储的最大频率是在P1上旋转后相等元素的最大数量。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to maximize the matching
// pairs between two permutation
// using left and right rotation
int maximumMatchingPairs(int perm1[],
                         int perm2[],
                         int n)
{
    // Left array store distance of element
    // from left side and right array store
    // distance of element from right side
    int left[n], right[n];
 
    // Map to store index of elements
    map mp1, mp2;
    for (int i = 0; i < n; i++) {
        mp1[perm1[i]] = i;
    }
    for (int j = 0; j < n; j++) {
        mp2[perm2[j]] = j;
    }
 
    for (int i = 0; i < n; i++) {
 
        // idx1 is index of element
        // in first permutation
 
        // idx2 is index of element
        // in second permutation
        int idx2 = mp2[perm1[i]];
        int idx1 = i;
 
        if (idx1 == idx2) {
 
            // If element if present on same
            // index on both permutations then
            // distance is zero
            left[i] = 0;
            right[i] = 0;
        }
        else if (idx1 < idx2) {
 
            // Calculate distance from left
            // and right side
            left[i] = (n - (idx2 - idx1));
            right[i] = (idx2 - idx1);
        }
        else {
 
            // Calculate distance from left
            // and right side
            left[i] = (idx1 - idx2);
            right[i] = (n - (idx1 - idx2));
        }
    }
 
    // Maps to store frequencies of elements
    // present in left and right arrays
    map freq1, freq2;
    for (int i = 0; i < n; i++) {
        freq1[left[i]]++;
        freq2[right[i]]++;
    }
 
    int ans = 0;
 
    for (int i = 0; i < n; i++) {
 
        // Find maximum frequency
        ans = max(ans, max(freq1[left[i]],
                           freq2[right[i]]));
    }
 
    // Return the result
    return ans;
}
 
// Driver Code
int main()
{
    // Given permutations P1 and P2
    int P1[] = { 5, 4, 3, 2, 1 };
    int P2[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(P1) / sizeof(P1[0]);
 
    // Function Call
    cout << maximumMatchingPairs(P1, P2, n);
    return 0;
}


Java
// Java program for
// the above approach
import java.util.*;
class GFG{
 
// Function to maximize the matching
// pairs between two permutation
// using left and right rotation
static int maximumMatchingPairs(int perm1[],
                                int perm2[],
                                int n)
{
  // Left array store distance of element
  // from left side and right array store
  // distance of element from right side
  int []left = new int[n];
  int []right = new int[n];
 
  // Map to store index of elements
  HashMap mp1 =  new HashMap<>();
  HashMap mp2 =  new HashMap<>();
   
  for (int i = 0; i < n; i++)
  {
    mp1.put(perm1[i], i);
  }
  for (int j = 0; j < n; j++)
  {
    mp2.put(perm2[j], j);
  }
 
  for (int i = 0; i < n; i++)
  {
    // idx1 is index of element
    // in first permutation
    // idx2 is index of element
    // in second permutation
    int idx2 = mp2.get(perm1[i]);
    int idx1 = i;
 
    if (idx1 == idx2)
    {
      // If element if present on same
      // index on both permutations then
      // distance is zero
      left[i] = 0;
      right[i] = 0;
    }
    else if (idx1 < idx2)
    {
      // Calculate distance from left
      // and right side
      left[i] = (n - (idx2 - idx1));
      right[i] = (idx2 - idx1);
    }
    else
    {
      // Calculate distance from left
      // and right side
      left[i] = (idx1 - idx2);
      right[i] = (n - (idx1 - idx2));
    }
  }
 
  // Maps to store frequencies of elements
  // present in left and right arrays
  HashMap freq1 = new HashMap<>();
  HashMap freq2 = new HashMap<>();
   
  for (int i = 0; i < n; i++)
  {
    if(freq1.containsKey(left[i]))
      freq1.put(left[i],
      freq1.get(left[i]) + 1);
    else
      freq1.put(left[i], 1);
    if(freq2.containsKey(right[i]))
      freq2.put(right[i],
      freq2.get(right[i]) + 1);
    else
      freq2.put(right[i], 1);
  }
 
  int ans = 0;
 
  for (int i = 0; i < n; i++)
  {
    // Find maximum frequency
    ans = Math.max(ans,
          Math.max(freq1.get(left[i]),
                   freq2.get(right[i])));
  }
 
  // Return the result
  return ans;
}
 
// Driver Code
public static void main(String[] args)
{
  // Given permutations P1 and P2
  int P1[] = {5, 4, 3, 2, 1};
  int P2[] = {1, 2, 3, 4, 5};
  int n = P1.length;
 
  // Function Call
  System.out.print(maximumMatchingPairs(P1, P2, n));
}
}
 
// This code is contributed by gauravrajput1


Python3
# Python3 program for the above approach
from collections import defaultdict
 
# Function to maximize the matching
# pairs between two permutation
# using left and right rotation
def maximumMatchingPairs(perm1, perm2, n):
 
    # Left array store distance of element
    # from left side and right array store
    # distance of element from right side
    left = [0] * n
    right = [0] * n
 
    # Map to store index of elements
    mp1 = {}
    mp2 = {}
    for i in range (n):
        mp1[perm1[i]] = i
     
    for j in range (n):
        mp2[perm2[j]] = j
     
    for i in range (n):
 
        # idx1 is index of element
        # in first permutation
 
        # idx2 is index of element
        # in second permutation
        idx2 = mp2[perm1[i]]
        idx1 = i
 
        if (idx1 == idx2):
 
            # If element if present on same
            # index on both permutations then
            # distance is zero
            left[i] = 0
            right[i] = 0
         
        elif (idx1 < idx2):
 
            # Calculate distance from left
            # and right side
            left[i] = (n - (idx2 - idx1))
            right[i] = (idx2 - idx1)
         
        else :
 
            # Calculate distance from left
            # and right side
            left[i] = (idx1 - idx2)
            right[i] = (n - (idx1 - idx2))
 
    # Maps to store frequencies of elements
    # present in left and right arrays
    freq1 = defaultdict (int)
    freq2 = defaultdict (int)
    for i in range (n):
        freq1[left[i]] += 1
        freq2[right[i]] += 1
 
    ans = 0
 
    for i in range( n):
 
        # Find maximum frequency
        ans = max(ans, max(freq1[left[i]],
                           freq2[right[i]]))
 
    # Return the result
    return ans
 
# Driver Code
if __name__ == "__main__":
     
    # Given permutations P1 and P2
    P1 = [ 5, 4, 3, 2, 1 ]
    P2 = [ 1, 2, 3, 4, 5 ]
    n = len(P1)
 
    # Function Call
    print(maximumMatchingPairs(P1, P2, n))
 
# This code is contributed by chitranayal


C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
  
// Function to maximize the matching
// pairs between two permutation
// using left and right rotation
static int maximumMatchingPairs(int []perm1,
                                int []perm2,
                                int n)
{
  // Left array store distance of element
  // from left side and right array store
  // distance of element from right side
  int []left = new int[n];
  int []right = new int[n];
  
  // Map to store index of elements
  Dictionary mp1=new Dictionary();
  Dictionary mp2=new Dictionary();
    
  for (int i = 0; i < n; i++)
  {
    mp1[perm1[i]] = i;
  }
  for (int j = 0; j < n; j++)
  {
    mp2[perm2[j]] = j;
  }
  
  for (int i = 0; i < n; i++)
  {
    // idx1 is index of element
    // in first permutation
    // idx2 is index of element
    // in second permutation
    int idx2 = mp2[perm1[i]];
    int idx1 = i;
  
    if (idx1 == idx2)
    {
      // If element if present on same
      // index on both permutations then
      // distance is zero
      left[i] = 0;
      right[i] = 0;
    }
    else if (idx1 < idx2)
    {
      // Calculate distance from left
      // and right side
      left[i] = (n - (idx2 - idx1));
      right[i] = (idx2 - idx1);
    }
    else
    {
      // Calculate distance from left
      // and right side
      left[i] = (idx1 - idx2);
      right[i] = (n - (idx1 - idx2));
    }
  }
  
  // Maps to store frequencies of elements
  // present in left and right arrays
  Dictionary freq1=new Dictionary ();
  Dictionary freq2=new Dictionary ();
    
  for (int i = 0; i < n; i++)
  {
    if(freq1.ContainsKey(left[i]))
      freq1[left[i]]++;
    else
      freq1[left[i]] = 1;
       
    if(freq2.ContainsKey(right[i]))
      freq2[right[i]]++;
    else
      freq2[right[i]] = 1;
  }
  
  int ans = 0;
  
  for (int i = 0; i < n; i++)
  {
    // Find maximum frequency
    ans = Math.Max(ans,
          Math.Max(freq1[left[i]],
                   freq2[right[i]]));
  }
  
  // Return the result
  return ans;
}
  
// Driver Code
public static void Main(string[] args)
{
  // Given permutations P1 and P2
  int []P1 = {5, 4, 3, 2, 1};
  int []P2 = {1, 2, 3, 4, 5};
  int n = P1.Length;
  
  // Function Call
  Console.Write(maximumMatchingPairs(P1, P2, n));
}
}
 
// This code is contributed by Rutvik_56


输出:
1



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