给定一个大小为 n 的数组和一个数字 k。我们必须修改数组 K 次。这里修改数组意味着在每个操作中我们可以用-arr[i]替换任何数组元素arr[i]。我们需要以这样的方式执行此操作,即经过K次操作后,数组的总和必须最大?
例子:
Input : arr[] = {-2, 0, 5, -1, 2}
K = 4
Output: 10
// Replace (-2) by -(-2), array becomes {2, 0, 5, -1, 2}
// Replace (-1) by -(-1), array becomes {2, 0, 5, 1, 2}
// Replace (0) by -(0), array becomes {2, 0, 5, 1, 2}
// Replace (0) by -(0), array becomes {2, 0, 5, 1, 2}
Input : arr[] = {9, 8, 8, 5}
K = 3
Output: 20
我们强烈建议您在继续解决方案之前单击此处进行练习。
我们在下面的帖子中讨论了 O(nk) 解决方案。
在 K 个否定后最大化数组总和 |设置 1
上面帖子中使用的想法是将数组中的最小元素 arr[i] 替换为 -arr[i] 以进行当前操作。这样我们就可以在 K 次操作后使数组的总和最大。一个有趣的例子是,一旦最小元素变为 0,我们就不需要再做任何更改了。
上述解决方案中使用的实现使用线性搜索来查找最小元素。上述解决方案的时间复杂度为 O(nk)
在这篇文章中,实现了一个优化的解决方案,它使用优先级队列(或二叉堆)来快速找到最小元素。
下面是这个想法的实现。它使用Java的PriorityQueue 类。
C++
// A PriorityQueue based C++ program to
// maximize array sum after k negations.
#include
using namespace std;
// Function to find Maximum sum
// after K negations
int MaxSum(int a[], int n, int k)
{
int sum = 0;
// Create a min heap for priority queue
priority_queue, greater> pq;
// Insert all elements in f array in priority_queue
for(int i = 0; i < n; i++)
{
pq.push(a[i]);
}
while (k--)
{
// Retrieve and remove min element
int temp = pq.top();
pq.pop();
// Modify the minimum element and
// add back to priority queue
temp = (temp) * -1;
pq.push(temp);
}
// Calculate the sum
while (!pq.empty())
{
sum = sum + pq.top();
pq.pop();
}
return sum;
}
// Driver Code
int main()
{
int a[] = { -2, 0, 5, -1, 2 };
int n = sizeof(a) / sizeof(a[0]);
int k = 4;
cout << MaxSum(a, n, k);
return 0;
}
// This code is contributed by Harshit Srivastava
Java
// A PriorityQueue based Java program to maximize array
// sum after k negations.
import java.util.*;
class maximizeSum
{
public static int maxSum(int[] a, int k)
{
// Create a priority queue and insert all array elements
// int
PriorityQueue pq = new PriorityQueue<>();
for (int x : a)
pq.add(x);
// Do k negations by removing a minimum element k times
while (k-- > 0)
{
// Retrieve and remove min element
int temp = pq.poll();
// Modify the minimum element and add back
// to priority queue
temp *= -1;
pq.add(temp);
}
// Compute sum of all elements in priority queue.
int sum = 0;
for (int x : pq)
sum += x;
return sum;
}
// Driver code
public static void main (String[] args)
{
int[] arr = {-2, 0, 5, -1, 2};
int k = 4;
System.out.println(maxSum(arr, k));
}
}
输出:
10
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。