给定从1 到 N的数字的两个排列P1和P2 ,任务是通过对P1执行循环左移或右移来找到给定排列中对应相同元素的最大计数。
例子:
Input: P1 = [5 4 3 2 1], P2 = [1 2 3 4 5]
Output: 1
Explanation:
We have a matching pair at index 2 for element 3.
Input: P1 = [1 3 5 2 4 6], P2 = [1 5 2 4 3 6]
Output: 3
Explanation:
Cyclic shift of second permutation towards right would give 6 1 5 2 4 3, and we get a match of 5, 2, 4. Hence, the answer is 3 matching pairs.
朴素的方法:朴素的方法是检查左右方向上的每个可能的移位,通过循环遍历形成的所有排列来计算匹配对的数量。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:可以优化上述朴素的方法。这个想法是让每个元素在单独的数组中存储该元素与左侧和右侧的位置之间的较小距离。因此,问题的解决方案将被计算为来自两个分离阵列的元素的最大频率。以下是步骤:
- 将排列P2的所有元素的位置存储在一个数组中(比如store[] )。
- 对于排列P1中的每个元素,执行以下操作:
- 找到当前元素在P2中的位置与P1 中的位置之间的差异(比如diff )。
- 如果 diff 小于 0,则将 diff 更新为(N – diff) 。
- 将当前差异 diff 的频率存储在地图中。
- 经过以上步骤,map中存储的最大频率就是在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
Javascript
1
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live