📌  相关文章
📜  使用相对端的元素以最少的替换找到所有可能的成对和

📅  最后修改于: 2022-05-13 01:56:04.634000             🧑  作者: Mango

使用相对端的元素以最少的替换找到所有可能的成对和

给定一个偶数长度N的数组arr[]和一个整数 K 表示数组中的数字范围,即数组中的数字在范围 [1, K] 内。任务是找到所有可能的相反索引对和最小替换,其中在任何替换中,数组的任何数量都可以更改为 [1, K] 范围内的任何其他数字。

注意:如果i到起点的距离和j到终点的距离相等,并且i位于数组的前半部分,而j位于数组的后半部分,则称两个索引ij是相反的。

例子:

方法:这个问题是基于扫描算法的。对于每一对,找到它可以采用的最大值和最小值并创建分段,以便可以实现最少的操作。找到重叠最多的段,并标记段中的总和。这样,可以找到组成相等对的最小和值。

下面是上述方法的实现。

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