📌  相关文章
📜  使数组中给定类型的所有对的总和相等所需的替换计数

📅  最后修改于: 2021-05-14 07:46:45             🧑  作者: Mango

给定长度为N的整数数组arr和整数K ,任务是找到要替换为范围[1,K]中的值的数组元素的数量,以使每对(arr [i],arr [N – 1 – i]具有相等的总和。

例子 :

天真的方法:
解决此问题的最简单方法可能是对X的所有可能值进行迭代,该值可以是12 * 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个替换。
  • 只需将两个对的所有对的mxmn插入两个不同的向量中,对它们进行排序并应用二分查找即可找到需要2个替换的对的数目。
  • 通过存储每个和的频率,使用Map查找不需要替换的对。
  • 最后,可以通过等式(N / 2-(需要2个替换的对+不需要替换的对))计算需要替换的对的数量

请按照以下步骤查找解决问题的方法:

  1. 找到最大和最小的所有对的常用3 [I],编曲[N – I – 1],并将它们分别存储在max_valuesmin_values载体。还要在地图中存储所有这些对的和的频率。
  2. 排序向量max_valuesmin_values。
  3. X = 2迭代到X = 2 * K ,对于X的每个值,找到替换的总数,如上面的方法中所述。将答案更新为:

下面是上述方法的实现:

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)