给定长度为N且偶数为K的数组arr [] ,任务是将替换数组元素的次数最小化为[1,K]范围内的整数,以使末尾所有等距元素对的总和的数组相等。
例子:
Input: arr[] = {1, 2, 4, 3}, K = 4
Output: 1
Explanation:
Replacing arr[2] by 2 modifies arr[] to {1, 2, 2, 3}.
arr[0] + arr[3] = 1 + 3 = 4.
arr[1] + arr[2] = 2 + 2 = 4.
Therefore, the sum of equidistant elements from the end of the array are equal(i.e., arr[i] + arr[N – 1 – i] = 4 for every i).
Input: arr[] = [1, 2, 1, 2], K = 2
Output: 0
方法:通过将两个值都更改为1 ,将对的最小可能总和(arr [i],arr [N – i – 1])为2,通过将两个值都更改为K ,最大可能的总和为2 * K 。因此,对于每对数字(在索引i和N – 1 – i处),l和r:
- 通过2个替换:可以实现范围[2,2 * K]之间的总和。
- 仅1个替换:
- 可以达到的最小总和,例如minSum ,是(min(L,R)+1) 。
- 可以实现的最大总和,例如maxSum ,是(max(L,R)+ K) 。
- 不可替换:总和(L + R)保留。使其成为pairSum 。
从以上结果推导出,对于一对(L,R) :
- 为了使总和在[2,minSum – 1]范围内,需要2次替换。
- 为了获得在[minSum,pairSum – 1]范围内的总和,需要进行1次替换。
- 为了获得sum pairSum ,不需要替换。
- 为了获得在[pairSum + 1,maxSum]范围内的总和,需要进行1次替换。
- 为了获得范围[maxSum +1,2 * K]的总和,需要2次替换。
因此,对于每对数组元素
- 从2个替换开始。
- 从minSum开始,需要减少1次更换。
- 对于pairSum ,需要的更换次数要少得多。
- 从pairSum + 1开始,需要1个额外的替换。
- 从maxSum + 1开始,还需要其他替换。
请按照以下步骤解决问题:
- 初始化一个大小为(2 * K + 2)的辅助数组,例如memo [] ,其中memo [i]表示使所有必需对的总和等于i – N所需的最小替换数。
- 使用变量i遍历索引[0,N / 2 – 1] 。
- 将线对的左元素,即arr [i]存储在L中,将线对的右元素,即arr [N – i – 1]存储在R中。
- 将备忘[min(L,R)+ 1]和备忘[L + R]减1。
- 将备忘[L + R + 1]和备忘[max(L,R)+ K +1]增加1。
- 初始化ANS如N来存储所需的移动和CURR的最小数目为N到备忘录[]的前缀和存储在每一个步骤。
- 找到数组memo []的前缀和,并在每次迭代中更新curr和ans的值(如果curr小于ans) 。
- 完成上述步骤后,将ans的值打印为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the minimum replacements
// required to make the sum of equidistant
// array elements from the end equal
void minReplacements(vector& nums, int k)
{
// Store the size of nums array
int N = nums.size();
// Initialize an auxiliary array
vector memo(k * 2 + 2, 0);
// Iterate nums in range[0, N/2-1]
for (int i = 0; i < N / 2; ++i) {
// Store the left element and
// the right element
int l = nums[i], r = nums[N - 1 - i];
// Decrement memo[min(l, r) + 1] by 1
--memo[min(l, r) + 1];
// Decrement memo[l + r] by 1
--memo[l + r];
// Increment memo[l + r + 1] by 1
++memo[l + r + 1];
// Increment memo[max(l, r) + k + 1] by 1
++memo[max(l, r) + k + 1];
}
// Store the minimum number of moves
int ans = N;
int curr = N;
// Find the prefix sum of memo[]
for (int i = 2; i <= k * 2; ++i) {
curr += memo[i];
// Update ans
ans = min(ans, curr);
}
// Print the answer
cout << ans;
}
// Driver Code
int main()
{
vector arr{ 1, 2, 4, 3 };
int K = 4;
// Function Call
minReplacements(arr, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.util.Arrays;
class GFG{
// Function to count the minimum replacements
// required to make the sum of equidistant
// array elements from the end equal
static void minReplacements(int[] nums, int k)
{
// Store the size of nums array
int N = nums.length;
// Initialize an auxiliary array
int[] memo = new int[(k * 2 + 2)];
Arrays.fill(memo, 0);
// Iterate nums in range[0, N/2-1]
for(int i = 0; i < N / 2; ++i)
{
// Store the left element and
// the right element
int l = nums[i], r = nums[N - 1 - i];
// Decrement memo[min(l, r) + 1] by 1
--memo[Math.min(l, r) + 1];
// Decrement memo[l + r] by 1
--memo[l + r];
// Increment memo[l + r + 1] by 1
++memo[l + r + 1];
// Increment memo[max(l, r) + k + 1] by 1
++memo[Math.max(l, r) + k + 1];
}
// Store the minimum number of moves
int ans = N;
int curr = N;
// Find the prefix sum of memo[]
for(int i = 2; i <= k * 2; ++i)
{
curr += memo[i];
// Update ans
ans = Math.min(ans, curr);
}
// Print the answer
System.out.println(ans);
}
// Driver code
public static void main(String[] args)
{
int[] arr = { 1, 2, 4, 3 };
int K = 4;
// Function Call
minReplacements(arr, K);
}
}
// This code is contributed by susmitakundugoaldanga
Python3
# Python3 program for the above approach
# Function to count the minimum replacements
# required to make the sum of equidistant
# array elements from the end equal
def minReplacements(nums, k):
# Store the size of nums array
N = len(nums)
# Initialize an auxiliary array
memo = [0]*(k * 2 + 2)
# Iterate nums in range[0, N/2-1]
for i in range(N//2):
# Store the left element and
# the right element
l, r = nums[i], nums[N - 1 - i]
# Decrement memo[min(l, r) + 1] by 1
memo[min(l, r) + 1] -= 1
# Decrement memo[l + r] by 1
memo[l + r] -= 1
# Increment memo[l + r + 1] by 1
memo[l + r + 1] += 1
# Increment memo[max(l, r) + k + 1] by 1
memo[max(l, r) + k + 1] += 1
# Store the minimum number of moves
ans = N
curr = N
# Find the prefix sum of memo[]
for i in range(2, 2 * k + 1):
curr += memo[i]
# Update ans
ans = min(ans, curr)
# Prthe answer
print (ans)
# Driver Code
if __name__ == '__main__':
arr =[1, 2, 4, 3]
K = 4
# Function Call
minReplacements(arr, K)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Function to count the minimum replacements
// required to make the sum of equidistant
// array elements from the end equal
static void minReplacements(int[] nums, int k)
{
// Store the size of nums array
int N = nums.Length;
// Initialize an auxiliary array
int[] memo = new int[(k * 2 + 2)];
for(int i = 0; i < k * 2 + 2; ++i)
{
memo[i] = 0;
}
// Iterate nums in range[0, N/2-1]
for(int i = 0; i < N / 2; ++i)
{
// Store the left element and
// the right element
int l = nums[i], r = nums[N - 1 - i];
// Decrement memo[min(l, r) + 1] by 1
--memo[Math.Min(l, r) + 1];
// Decrement memo[l + r] by 1
--memo[l + r];
// Increment memo[l + r + 1] by 1
++memo[l + r + 1];
// Increment memo[max(l, r) + k + 1] by 1
++memo[Math.Max(l, r) + k + 1];
}
// Store the minimum number of moves
int ans = N;
int curr = N;
// Find the prefix sum of memo[]
for(int i = 2; i <= k * 2; ++i)
{
curr += memo[i];
// Update ans
ans = Math.Min(ans, curr);
}
// Print the answer
Console.WriteLine(ans);
}
// Driver code
public static void Main()
{
int[] arr = { 1, 2, 4, 3 };
int K = 4;
// Function Call
minReplacements(arr, K);
}
}
// This code is contributed by sanjoy_62
输出:
1
时间复杂度: O(N + K)
辅助空间: O(K)