Java程序使用循环旋转最大化给定排列中对应相同元素的计数
给定从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)
Efficient Approach:可以优化上述幼稚的方法。这个想法是让每个元素将这个元素从左侧和右侧的位置之间的较小距离存储在单独的数组中。因此,问题的解决方案将计算为两个分离数组中元素的最大频率。以下是步骤:
- 将排列P2的所有元素的位置存储在一个数组中(比如store[] )。
- 对于排列P1中的每个元素,请执行以下操作:
- 找出P2中当前元素的位置与P1中的位置之间的差异(例如diff )。
- 如果 diff 小于 0 则将 diff 更新为(N – diff) 。
- 将当前差异差异的频率存储在地图中。
- 经过以上步骤,map中存储的最大频率就是在P1上旋转后的最大相等元素个数。
下面是上述方法的实现:
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
1
时间复杂度: O(N)
辅助空间: O(N)
有关更多详细信息,请参阅有关使用循环旋转最大化给定排列中相应相同元素的计数的完整文章!