给定长度为N的整数数组arr和整数K ,任务是找到要替换为范围[1,K]中的值的数组元素的数量,以使每对(arr [i],arr [N – 1 – i]具有相等的总和。
例子 :
Input: arr[] = {1, 2, 2, 1}, K = 3
Output: 1
Explanation:
Replace arr[0] with 3, so that the array becomes {3, 2, 2, 1}.
Now, it can be seen that arr[0] + arr[3] = arr[1] + arr[2] = 4.
Input: arr[] = {1, 2, 1, 2, 1, 2}
Output: 0
Explanation:
No need to make any changes as arr[0] + arr[5] = arr[1] + arr[4] = arr[2] + arr[3] = 3
天真的方法:
解决此问题的最简单方法可能是对X的所有可能值进行迭代,该值可以是1到2 * K范围内的任何数字,并找到达到等于X的对和所需的运算数。最后返回所有操作的最少更换次数。
时间复杂度: O(N * K)
辅助空间: O(1)
高效的方法:可以通过以下观察来优化上述方法:
- X显然可以采用[2,2 * K]范围内的值。
- 考虑成对的arr [i]和arr [N – i – 1] ,可以观察到,在0、1或2个替换中,任何一对的总和都可以等于X。
- 让这两个数字的最大值为mx ,最小值为mn 。在一次替换中,该对的总和将在[mn +1,mx + K]范围内。
- mx小于(X-K)且mn大于或等于X的对将需要2个替换。
- 只需将两个对的所有对的mx和mn插入两个不同的向量中,对它们进行排序并应用二分查找即可找到需要2个替换的对的数目。
- 通过存储每个和的频率,使用Map查找不需要替换的对。
- 最后,可以通过等式(N / 2-(需要2个替换的对+不需要替换的对))计算需要替换的对的数量。
请按照以下步骤查找解决问题的方法:
- 找到最大和最小的所有对的常用3 [I],编曲[N – I – 1],并将它们分别存储在max_values和min_values载体。还要在地图中存储所有这些对的和的频率。
- 排序向量max_values和min_values。
- 从X = 2迭代到X = 2 * K ,对于X的每个值,找到替换的总数,如上面的方法中所述。将答案更新为:
answer = min ( answer, 2 * (number of pairs for which we need to make 2 replacements) + (number of pairs for which we need to make one replacement) ).
Illustration :
arr[] = { 1, 2, 2, 1 }, K = 3
max_values = {1, 2}
min_values = {1, 2}
map = {{2, 1}, {4, 1}}
At X = 4, minimum replacement is required, that is, only 1 replacement, either conversion arr[0] to 3 or arr[3] to 3, is required to make the sum of all pairs equal to 4.
下面是上述方法的实现:
C++
// C++ Program to implement the
// above approach
#include
#define int long long int
using namespace std;
const int inf = 1e18;
// Function to find the minimum
// replacements required
int minimumReplacement(int* arr, int N,
int K)
{
int ans = inf;
// Stores the maximum and minimum
// values for every pair of
// the form arr[i], arr[n-i-1]
vector max_values;
vector min_values;
// Map for storing frequencies
// of every sum formed by pairs
map sum_equal_to_x;
for (int i = 0; i < N / 2; i++) {
// Minimum element in the pair
int mn = min(arr[i], arr[N - i - 1]);
// Maximum element in the pair
int mx = max(arr[i], arr[N - i - 1]);
// Incrementing the frequency of
// sum encountered
sum_equal_to_x[arr[i]
+ arr[N - i - 1]]++;
// Insert minimum and maximum values
min_values.push_back(mn);
max_values.push_back(mx);
}
// Sorting the vectors
sort(max_values.begin(),
max_values.end());
sort(min_values.begin(),
min_values.end());
// Iterate over all possible values of x
for (int x = 2; x <= 2 * K; x++) {
// Count of pairs for which x > x + k
int mp1
= lower_bound(max_values.begin(),
max_values.end(), x - K)
- max_values.begin();
// Count of pairs for which x < mn + 1
int mp2
= lower_bound(min_values.begin(),
min_values.end(), x)
- min_values.begin();
// Count of pairs requiring 2 replacements
int rep2 = mp1 + (N / 2 - mp2);
// Count of pairs requiring no replacements
int rep0 = sum_equal_to_x[x];
// Count of pairs requiring 1 replacement
int rep1 = (N / 2 - rep2 - rep0);
// Update the answer
ans = min(ans, rep2 * 2 + rep1);
}
// Return the answer
return ans;
}
// Driver Code
int32_t main()
{
int N = 4;
int K = 3;
int arr[] = { 1, 2, 2, 1 };
cout << minimumReplacement(arr, N, K);
return 0;
}
Java
// Java program implement
// the above approach
import java.util.*;
import java.io.*;
class GFG{
static int inf = (int)1e18;
// Function to find the minimum
// replacements required
static int minimumReplacement(int[] arr, int N,
int K)
{
int ans = inf;
// Stores the maximum and minimum
// values for every pair of
// the form arr[i], arr[n-i-1]
ArrayList max_values = new ArrayList<>();
ArrayList min_values = new ArrayList<>();
// Map for storing frequencies
// of every sum formed by pairs
Map sum_equal_to_x = new HashMap<>();
for(int i = 0; i < N / 2; i++)
{
// Minimum element in the pair
int mn = Math.min(arr[i], arr[N - i - 1]);
// Maximum element in the pair
int mx = Math.max(arr[i], arr[N - i - 1]);
// Incrementing the frequency of
// sum encountered
sum_equal_to_x.put(arr[i] +
arr[N - i - 1],
sum_equal_to_x.getOrDefault(arr[i] +
arr[N - i - 1],
0) + 1);
// Insert minimum and maximum values
min_values.add(mn);
max_values.add(mx);
}
// Sorting the vectors
Collections.sort(max_values);
Collections.sort(min_values);
// Iterate over all possible values of x
for(int x = 2; x <= 2 * K; x++)
{
// Count of pairs for which x > x + k
int mp1 = max_values.indexOf(x - K);
// Count of pairs for which x < mn + 1
int mp2 = min_values.indexOf(x);
// Count of pairs requiring 2 replacements
int rep2 = mp1 + (N / 2 - mp2);
// Count of pairs requiring no replacements
int rep0 = sum_equal_to_x.getOrDefault(x, -1);
// Count of pairs requiring 1 replacement
int rep1 = (N / 2 - rep2 - rep0);
// Update the answer
ans = Math.min(ans, rep2 * 2 + rep1);
}
// Return the answer
return ans;
}
// Driver Code
public static void main (String[] args)
{
int N = 4;
int K = 3;
int arr[] = { 1, 2, 2, 1 };
System.out.print(minimumReplacement(arr, N, K));
}
}
// This code is contributed by offbeat
Python3
# Python3 program to implement the
# above approach
inf = 10**18
def firstOccurance(numbers, length,
searchnum):
answer = -1
start = 0
end = length - 1
while start <= end:
middle = (start + end) // 2
if numbers[middle] == searchnum:
answer = middle
end = middle - 1
elif numbers[middle] > searchnum:
end = middle - 1
else:
start = middle + 1
return answer
# Function to find the minimum
# replacements required
def minimumReplacement(arr, N, K):
ans = inf
# Stores the maximum and minimum
# values for every pair of
# the form arr[i], arr[n-i-1]
max_values = []
min_values = []
# Map for storing frequencies
# of every sum formed by pairs
sum_equal_to_x = dict()
for i in range(N // 2):
# Minimum element in the pair
mn = min(arr[i], arr[N - i - 1])
# Maximum element in the pair
mx = max(arr[i], arr[N - i - 1])
# Incrementing the frequency of
# sum encountered
if(arr[i] + arr[N - i - 1] not in sum_equal_to_x):
sum_equal_to_x[arr[i] + arr[N - i - 1]] = 0
sum_equal_to_x[arr[i] + arr[N - i - 1]] += 1
# Insert minimum and maximum values
min_values.append(mn)
max_values.append(mx)
max_values.sort()
min_values.sort()
# Iterate over all possible values of x
for x in range(2, 2 * K + 1):
# Count of pairs for which x > x + k
mp1 = firstOccurance(
max_values, len(max_values), x - K)
# Count of pairs for which x < mn + 1
mp2 = firstOccurance(
min_values, len(min_values), x)
# Count of pairs requiring 2 replacements
rep2 = mp1 + (N // 2 - mp2)
# Count of pairs requiring no replacements
if x in sum_equal_to_x:
rep0 = sum_equal_to_x[x]
else:
rep0 = 0
# Count of pairs requiring 1 replacement
rep1 = (N // 2 - rep2 - rep0)
# Update the answer
ans = min(ans, rep2 * 2 + rep1)
# Return the answer
return ans
# Driver Code
if __name__=='__main__':
N = 4
K = 3
arr = [ 1, 2, 2, 1 ]
print(minimumReplacement(arr, N, K))
# This code is contributed by pratham76
C#
// C# program implement
// the above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
// Function to find the minimum
// replacements required
static int minimumReplacement(int[] arr, int N,
int K)
{
int ans = int.MaxValue;
// Stores the maximum and minimum
// values for every pair of
// the form arr[i], arr[n-i-1]
ArrayList max_values = new ArrayList();
ArrayList min_values = new ArrayList();
// Map for storing frequencies
// of every sum formed by pairs
Dictionary sum_equal_to_x = new Dictionary();
for(int i = 0; i < N / 2; i++)
{
// Minimum element in the pair
int mn = Math.Min(arr[i], arr[N - i - 1]);
// Maximum element in the pair
int mx = Math.Max(arr[i], arr[N - i - 1]);
// Incrementing the frequency of
// sum encountered
sum_equal_to_x[arr[i] + arr[N - i - 1]] =
sum_equal_to_x.GetValueOrDefault(arr[i] +
arr[N - i - 1], 0) + 1;
// Insert minimum and maximum values
min_values.Add(mn);
max_values.Add(mx);
}
// Sorting the vectors
max_values.Sort();
min_values.Sort();
// Iterate over all possible values of x
for(int x = 2; x <= 2 * K; x++)
{
// Count of pairs for which x > x + k
int mp1 = max_values.IndexOf(x - K);
// Count of pairs for which x < mn + 1
int mp2 = min_values.IndexOf(x);
// Count of pairs requiring 2 replacements
int rep2 = mp1 + (N / 2 - mp2);
// Count of pairs requiring no replacements
int rep0 = sum_equal_to_x.GetValueOrDefault(
x, -1);
// Count of pairs requiring 1 replacement
int rep1 = (N / 2 - rep2 - rep0);
// Update the answer
ans = Math.Min(ans, rep2 * 2 + rep1);
}
// Return the answer
return ans;
}
// Driver Code
public static void Main(string[] args)
{
int N = 4;
int K = 3;
int []arr = { 1, 2, 2, 1 };
Console.Write(minimumReplacement(arr, N, K));
}
}
// This code is contributed by rutvik_56
1
时间复杂度: O(NlogN)
辅助空间: O(N)