Open In App

Minimizing maximum value by Pairwise Multiplication

Last Updated : 06 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A of N integers where N is even. Consider an empty array B and perform the following operations on A exactly N/2 times, and you have to perform the operations in such a way that the maximum value on B is minimized. Find this value.

  • Choose any two elements of A and erase them from A.
  • Append the product of those two elements at the end of B.

Examples:

Input: N = 4, A = {-12, 17, -13, 17}
Output: -204
Explanation:

  • Step 1: Select 17 and -12. Remove from A. Add (17 * -12) = -204 in B.
  • Step 2: Select 17 and -13. Remove from B. Add (17 * -13) = -221 in B.

B = {-204, -221}. -204 is the max value of B.

Input: N = 2, A = {2, 6}
Output: 12
Explanation: B = {12}

Approach: This can be solved with the following idea:

Using priority queue, we can see which value is minimum and maximum as it always optimal to choose one maximum and minimum value to get minimized value of B.

Below are the steps involved:

  • Intialize a priority_queue pq.
  • Separate positive and negative elements in separate vectors.
  • Add multiplication of positive and negative elements in pq.
  • Return the top element of pq as it will be maximum as it is minimum value.

Below is the implementation of the code:

C++




// C++ Implementation
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Function to maximum of minimum value B[]
long long maximumMultiple(int N, int A[])
{
    // code here
    priority_queue<long long> pq;
 
    // Sort the array
    sort(A, A + N);
    long long i = 0;
    long long neg = 0;
    long long pos = 0;
    vector<long> first;
    vector<long> second;
 
    // Iterate in array
    while (i < N) {
 
        // If the element is negative
        if (A[i] < 0) {
            second.push_back(A[i]);
            neg++;
        }
 
        // If the element is positive
        else {
            first.push_back(A[i]);
            pos++;
        }
        i++;
    }
 
    // If the count of neg and pos is equal
    if (neg == pos) {
        i = 0;
        while (i < first.size()) {
            pq.push(first[i] * 1LL * second[i]);
            i++;
        }
 
        // Return the maximum value
        return pq.top();
    }
 
    // If the pos count is more than neg
    else if (pos > neg) {
        i = 0;
        int end = first.size() - 1;
        while (i < second.size()) {
            pq.push(first[end] * 1LL * second[i]);
            i++;
            end--;
        }
        int start = 0;
 
        // As count of pos is more
        while (start < end) {
            pq.push(first[start] * 1LL * first[end]);
            start++;
            end--;
        }
 
        // Return the maximum value
        return pq.top();
    }
 
    // If count of neg is more than
    else {
        i = 0;
        int end = 0;
        while (i < first.size()) {
            pq.push(first[i] * 1LL * second[end]);
            i++;
            end++;
        }
        int start = second.size() - 1;
        // As count of neg is more
        while (start > end) {
            pq.push(second[start] * second[end] * 1LL);
            start--;
            end++;
        }
 
        // Return the maximum value
        return pq.top();
    }
}
 
// Driver code
int main()
{
 
    int N = 4;
 
    int A[] = { -12, 17, -13, 17 };
 
    // Function Call
    cout << maximumMultiple(N, A);
    return 0;
}


Java




import java.util.*;
public class GFG {
 
    // Function to maximum of the minimum value B[]
    static long MaximumMultiple(int N, int[] A)
    {
        // Create a max heap
        PriorityQueue<Long> pq = new PriorityQueue<>(
            Collections.reverseOrder());
        // Sort the array
        List<Long> first = new ArrayList<>();
        List<Long> second = new ArrayList<>();
        long i = 0;
        long neg = 0;
        long pos = 0;
 
        // Iterate in the array
        while (i < N) {
            // If the element is negative
            if (A[(int)i] < 0) {
                second.add((long)A[(int)i]);
                neg++;
            }
            // If the element is positive
            else {
                first.add((long)A[(int)i]);
                pos++;
            }
            i++;
        }
 
        // If the count of the neg and pos is equal
        if (neg == pos) {
            i = 0;
            while (i < first.size()) {
                pq.add(first.get((int)i)
                       * second.get((int)i));
                i++;
            }
            // Return the maximum value
            return pq.peek();
        }
        // If the pos count is more than neg
        else if (pos > neg) {
            i = 0;
            int end = first.size() - 1;
            while (i < second.size()) {
                pq.add(first.get(end) * second.get((int)i));
                i++;
                end--;
            }
            int start = 0;
            // As count of pos is more
            while (start < end) {
                pq.add(first.get(start) * first.get(end));
                start++;
                end--;
            }
            // Return the maximum value
            return pq.peek();
        }
        // If count of neg is more than pos
        else {
            i = 0;
            int end = 0;
            while (i < first.size()) {
                pq.add(first.get((int)i)
                       * second.get((int)end));
                i++;
                end++;
            }
            int start = second.size() - 1;
            // As count of neg is more
            while (start > end) {
                pq.add(second.get(start) * second.get(end));
                start--;
                end++;
            }
            // Return the maximum value
            return pq.peek();
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int N = 4;
        int[] A = { -12, 17, -13, 17 };
 
        // Function Call
        System.out.println(MaximumMultiple(N, A));
    }
}


Python3




class PriorityQueue:
    def __init__(self):
        self.values = []
     
    def push(self, val):
        self.values.append(val)
        self.bubbleUp()
    # Move the newly added element to the appropriate position to maintain the max-heap property
    def bubbleUp(self):
        index = len(self.values) - 1
        element = self.values[index]
        while index > 0:
            parentIndex = (index - 1) // 2
            parent = self.values[parentIndex]
            if element <= parent:
                break
            # Swap the element and its parent if the element is greater
            self.values[parentIndex] = element
            self.values[index] = parent
            index = parentIndex
     
    # Get the maximum (top) element of the max-heap
    def top(self):
        return self.values[0]
 
def maximumMultiple(N, A):
    # Create a max-heap (priority queue)
    pq = PriorityQueue()
     
    # Sort the array A in ascending order
    A.sort()
    i = 0
    neg = 0
    pos = 0
    first = []
    second = []
     
    # Split the array A into positive and negative elements
    while i < N:
        if A[i] < 0:
            second.append(A[i])
            neg += 1
        else:
            first.append(A[i])
            pos += 1
        i += 1
    if neg == pos:
        # If the count of negative and positive elements is equal
        i = 0
        while i < len(first):
            pq.push(first[i] * second[i])
            # Calculate and push the product of corresponding elements
            i += 1
        return pq.top()
        # Return the maximum value from the max-heap
    elif pos > neg:
        # If the count of positive elements is greater than negative elements
        i = 0
        end = len(first) - 1
        while i < len(second):
            pq.push(first[end] * second[i])
            # Calculate and push the product of elements from the two arrays
            i += 1
            end -= 1
        start = 0
        while start < end:
            pq.push(first[start] * first[end])
            # Calculate and push the product of elements from the first array
            start += 1
            end -= 1
        return pq.top()
        # Return the maximum value from the max-heap
    else:
        # If the count of negative elements is greater than positive elements
        i = 0
        end = 0
        while i < len(first):
            pq.push(first[i] * second[end])
            # Calculate and push the product of elements from the two arrays
            i += 1
            end += 1
        start = len(second) - 1
        while start > end:
            pq.push(second[start] * second[end])
            # Calculate and push the product of elements from the second array
            start -= 1
            end += 1
            # Return the maximum value from the max-heap
        return pq.top()
 
N = 4
A = [-12, 17, -13, 17]
print(maximumMultiple(N, A))


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG
{
    // Function to maximum of the minimum value B[]
    static long MaximumMultiple(int N, int[] A)
    {
        // Create a max heap
        PriorityQueue<long> pq = new PriorityQueue<long>();
        // Sort the array
        Array.Sort(A);
        long i = 0;
        long neg = 0;
        long pos = 0;
        List<long> first = new List<long>();
        List<long> second = new List<long>();
        // Iterate in the array
        while (i < N)
        {
            // If the element is negative
            if (A[i] < 0)
            {
                second.Add(A[i]);
                neg++;
            }
            // If the element is positive
            else
            {
                first.Add(A[i]);
                pos++;
            }
            i++;
        }
        // If the count of the neg and pos is equal
        if (neg == pos)
        {
            i = 0;
            while (i < first.Count)
            {
                pq.Push(first[(int)i] * 1L * second[(int)i]);
                i++;
            }
            // Return the maximum value
            return pq.Top();
        }
        // If the pos count is more than neg
        else if (pos > neg)
        {
            i = 0;
            int end = first.Count - 1;
            while (i < second.Count)
            {
                pq.Push(first[end] * 1L * second[(int)i]);
                i++;
                end--;
            }
            int start = 0;
            // As count of pos is more
            while (start < end)
            {
                pq.Push(first[start] * 1L * first[end]);
                start++;
                end--;
            }
            // Return the maximum value
            return pq.Top();
        }
        // If count of neg is more than pos
        else
        {
            i = 0;
            int end = 0;
            while (i < first.Count)
            {
                pq.Push(first[(int)i] * 1L * second[(int)end]);
                i++;
                end++;
            }
            int start = second.Count - 1;
            // As count of neg is more
            while (start > end)
            {
                pq.Push(second[start] * second[(int)end] * 1L);
                start--;
                end++;
            }
            // Return the maximum value
            return pq.Top();
        }
    }
    // Driver code
    static void Main()
    {
        int N = 4;
        int[] A = { -12, 17, -13, 17 };
 
        // Function Call
        Console.WriteLine(MaximumMultiple(N, A));
    }
}
// PriorityQueue class to simulate a max heap
class PriorityQueue<T> where T : IComparable<T>
{
    private List<T> heap;
 
    public PriorityQueue()
    {
        heap = new List<T>();
    }
    public int Count
    {
        get { return heap.Count; }
    }
    public void Push(T value)
    {
        heap.Add(value);
        int currentIndex = heap.Count - 1;
        int parentIndex = (currentIndex - 1) / 2;
        while (parentIndex >= 0 && heap[parentIndex].CompareTo(heap[currentIndex]) < 0)
        {
            Swap(parentIndex, currentIndex);
            currentIndex = parentIndex;
            parentIndex = (currentIndex - 1) / 2;
        }
    }
    public T Pop()
    {
        if (heap.Count == 0)
        {
            throw new InvalidOperationException("PriorityQueue is empty");
        }
        T root = heap[0];
        int lastIndex = heap.Count - 1;
        heap[0] = heap[lastIndex];
        heap.RemoveAt(lastIndex);
        int currentIndex = 0;
        while (true)
        {
            int leftChildIndex = 2 * currentIndex + 1;
            int rightChildIndex = 2 * currentIndex + 2;
            int swapIndex = currentIndex;
 
            if (leftChildIndex < heap.Count && heap[leftChildIndex].CompareTo(heap[swapIndex]) > 0)
            {
                swapIndex = leftChildIndex;
            }
            if (rightChildIndex < heap.Count && heap[rightChildIndex].CompareTo(heap[swapIndex]) > 0)
            {
                swapIndex = rightChildIndex;
            }
            if (swapIndex == currentIndex)
            {
                break;
            }
            Swap(currentIndex, swapIndex);
            currentIndex = swapIndex;
        }
        return root;
    }
    public T Top()
    {
        if (heap.Count == 0)
        {
            throw new InvalidOperationException("PriorityQueue is empty");
        }
        return heap[0];
    }
    private void Swap(int index1, int index2)
    {
        T temp = heap[index1];
        heap[index1] = heap[index2];
        heap[index2] = temp;
    }
}


Javascript




class PriorityQueue {
    constructor() {
        this.values = [];
    }
 
    push(val) {
        this.values.push(val);
        this.bubbleUp();
    }
 
    // Move the newly added element to the appropriate position to maintain the max-heap property
    bubbleUp() {
        let index = this.values.length - 1;
        const element = this.values[index];
 
        while (index > 0) {
            let parentIndex = Math.floor((index - 1) / 2);
            let parent = this.values[parentIndex];
 
            if (element <= parent) break;
 
            // Swap the element and its parent if the element is greater
            this.values[parentIndex] = element;
            this.values[index] = parent;
            index = parentIndex;
        }
    }
 
    // Get the maximum (top) element of the max-heap
    top() {
        return this.values[0];
    }
}
 
function maximumMultiple(N, A) {
    const pq = new PriorityQueue(); // Create a max-heap (priority queue)
 
    A.sort((a, b) => a - b); // Sort the array A in ascending order
    let i = 0;
    let neg = 0;
    let pos = 0;
    const first = [];
    const second = [];
 
    // Split the array A into positive and negative elements
    while (i < N) {
        if (A[i] < 0) {
            second.push(A[i]);
            neg++;
        } else {
            first.push(A[i]);
            pos++;
        }
        i++;
    }
 
    if (neg === pos) {
        // If the count of negative and positive elements is equal
        i = 0;
        while (i < first.length) {
            pq.push(first[i] * second[i]); // Calculate and push the product of corresponding elements
            i++;
        }
        return pq.top(); // Return the maximum value from the max-heap
    } else if (pos > neg) {
        // If the count of positive elements is greater than negative elements
        i = 0;
        let end = first.length - 1;
        while (i < second.length) {
            pq.push(first[end] * second[i]); // Calculate and push the product of elements from the two arrays
            i++;
            end--;
        }
        let start = 0;
        while (start < end) {
            pq.push(first[start] * first[end]); // Calculate and push the product of elements from the first array
            start++;
            end--;
        }
        return pq.top(); // Return the maximum value from the max-heap
    } else {
        // If the count of negative elements is greater than positive elements
        i = 0;
        let end = 0;
        while (i < first.length) {
            pq.push(first[i] * second[end]); // Calculate and push the product of elements from the two arrays
            i++;
            end++;
        }
        let start = second.length - 1;
        while (start > end) {
            pq.push(second[start] * second[end]); // Calculate and push the product of elements from the second array
            start--;
            end++;
        }
        return pq.top(); // Return the maximum value from the max-heap
    }
}
 
const N = 4;
const A = [-12, 17, -13, 17];
 
console.log(maximumMultiple(N, A));


Output

-204















Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads