📌  相关文章
📜  在 K 个否定后最大化数组总和 | 2套

📅  最后修改于: 2021-10-26 06:27:26             🧑  作者: Mango

给定一个大小为 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 现场工作专业课程学生竞争性编程现场课程