使用相对端的元素以最少的替换找到所有可能的成对和
给定一个偶数长度N的数组arr[]和一个整数 K 表示数组中的数字范围,即数组中的数字在范围 [1, K] 内。任务是找到所有可能的相反索引对和最小替换,其中在任何替换中,数组的任何数量都可以更改为 [1, K] 范围内的任何其他数字。
注意:如果i到起点的距离和j到终点的距离相等,并且i位于数组的前半部分,而j位于数组的后半部分,则称两个索引i和j是相反的。
例子:
Input: arr[] = {1, 2, 4, 3}, K = 4
Output: 4 6
Explanation: Initially the pair sum is 1+3 = 4 and 2+4 = 6 which is not equal.
Replace 4 with 2 in one step (minimum moves) and it will give two pairs having sum 4.
Or change the 1 to 3 in one step, that will give two pairs having sum 6.
So there are two possible values of equal sum of all pairs, 4 and 6, in minimum moves.
Input: arr[] = {1, 2, 4, 6, 5, 3}, K = 6
Output: 7
Explanation: The three different pair sums are 4, 7, and 10.
Change 3 to 6 and 6 to 3. and this will give all the pair sum as 7 with minimum changes.
Notice here pair sum cannot be made 4 as {4, 6} itself will require 2 .
So total changes will not be minimum.
And also pair sum cannot be made 10 as then 3 should be changed to 9 or 1 to 7.
Both the values lies outside the range [1, 6].
方法:这个问题是基于扫描算法的。对于每一对,找到它可以采用的最大值和最小值并创建分段,以便可以实现最少的操作。找到重叠最多的段,并标记段中的总和。这样,可以找到组成相等对的最小和值。
下面是上述方法的实现。
C++
#include
using namespace std;
// Function to find the possible values
void findValues(vector arr, int K)
{
int N = arr.size();
int range[(K * 2) + 2] = { 0 };
for (int i = 0; i < N / 2; i++) {
int mini = min(arr[i], arr[N - 1 - i]) + 1;
int maxi = max(arr[i], arr[N - 1 - i]) + K;
int total = arr[i] + arr[N - 1 - i];
// Using the sweeping the algorithm
// Increment the array
range[mini]--;
range[maxi + 1]++;
range[total]--;
range[total + 1]++;
}
int count = N;
int mini = INT_MAX;
int value = 0;
for (int i = 2; i < (K * 2) + 1; i++) {
count += range[i];
mini = min(mini, count);
}
count = N;
for (int i = 2; i < (K * 2) + 1; i++) {
count += range[i];
if (count == mini) {
cout << i << " ";
}
}
}
// Driver code
int main()
{
vector arr = { 1, 2, 4, 3 };
int K = 4;
findValues(arr, K);
return 0;
}
// This code is contributed by Potta Lokesh
Java
// Java code to implement above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the possible values
public static void findValues(int arr[],
int K)
{
int N = arr.length;
int range[] = new int[K * 2 + 2];
for (int i = 0; i < N / 2; ++i) {
int min
= Math.min(arr[i],
arr[N - 1 - i])
+ 1;
int max
= Math.max(arr[i],
arr[N - 1 - i])
+ K;
int total = arr[i]
+ arr[N - 1 - i];
// Using the sweeping the algorithm
// Increment the array
range[min]--;
range[max + 1]++;
range[total]--;
range[total + 1]++;
}
int count = N;
int min = Integer.MAX_VALUE;
int value = 0;
for (int i = 2; i < K * 2 + 1;
++i) {
count += range[i];
min = Integer.min(min, count);
}
count = N;
for (int i = 2; i < K * 2 + 1;
++i) {
count += range[i];
if (count == min) {
System.out.print(i + " ");
}
}
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 4, 3 };
int K = 4;
findValues(arr, K);
}
}
Python3
# Python program for the above approach
import sys
# Function to find the possible values
def findValues(arr, K):
N = len(arr)
ranges = [0] * ((K * 2) + 2)
for i in range(0, N // 2):
mini = min(arr[i], arr[N - 1 - i]) + 1
maxi = max(arr[i], arr[N - 1 - i]) + K
total = arr[i] + arr[N - 1 - i]
# Using the sweeping the algorithm
# Increment the array
ranges[mini] = ranges[mini] - 1
ranges[maxi + 1] = ranges[maxi + 1] + 1
ranges[total] = ranges[total] - 1
ranges[total + 1] = ranges[total + 1] + 1
count = N
mini = sys.maxsize
value = 0
for i in range(2, K*2+1):
count = count + ranges[i]
mini = min(mini, count)
count = N
for i in range(2, K*2+1):
count = count + ranges[i]
if (count == mini):
print(i, end=" ")
# Driver code
arr = [1, 2, 4, 3]
K = 4
findValues(arr, K)
# This code is contributed by Taranpreet
C#
using System;
public class GFG{
// Function to find the possible values
public static void findValues(int[] arr,
int K)
{
int N = arr.Length;
int[] range = new int[K * 2 + 2];
for (int i = 0; i < N / 2; ++i) {
int min
= Math.Min(arr[i],
arr[N - 1 - i])
+ 1;
int max
= Math.Max(arr[i],
arr[N - 1 - i])
+ K;
int total = arr[i]
+ arr[N - 1 - i];
// Using the sweeping the algorithm
// Increment the array
range[min]--;
range[max + 1]++;
range[total]--;
range[total + 1]++;
}
int count = N;
int mn = Int32.MaxValue;
for (int i = 2; i < K * 2 + 1;
++i) {
count += range[i];
mn = Math.Min(mn, count);
}
count = N;
for (int i = 2; i < K * 2 + 1;
++i) {
count += range[i];
if (count == mn) {
Console.Write(i + " ");
}
}
}
// Driver code
static public void Main (){
int[] arr = { 1, 2, 4, 3 };
int K = 4;
findValues(arr, K);
}
}
// This code is contributed by hrithikgarg03188.
Javascript
4 6
时间复杂度: O(K)
辅助空间: O(K)