Minimize the sum of roots of a given polynomial - GeeksforGeeks

03 Jun, 2021
Given an array whose elements represent the coefficients of a polynomial of degree n, if the polynomial has a degree n then the array will have n+1 elements (one extra for the constant of a polynomial). Swap some elements of the array and print the resulting array such that the sum of the roots of the given polynomial is as minimum as possible irrespective of the nature of the roots.Note that: except the first element of the array elements can be 0 also and the degree of the polynomial is always greater than 1.
Examples: 
Input : -4 1 6 -3 -2 -1
Output : 1 6 -4 -3 -2 -1
        Here, the array is -4, 1, 6, -3, -2, -1
        i.e the polynomial is -4.x^5 + 1.x^4 + 6.x^3 - 3.x^2 - 2.x^1 - 1
        minimum sum = -6 

Input : -9 0 9
Output :-9 0 9
       Here polynomial is 
       -9.x^2 + 0.x^1 + 9
       minimum sum = 0
Solution : Let us recall the fact about the sum of the roots of a polynomial if a polynomial p(x) = a.x^n + b.x^n-1 + c.x^n-2 + ... + k, then the sum of roots of a polynomial is given by -b/a. Please see Vieta’s formulas for details.We have to minimize -b/a i.e to maximize b/a i.e maximize b and minimize a. So if somehow we are able to maximize b and minimize a, we will swap the values of the coefficients and copy the rest of the array as it is.
There will be four cases : Case #1: when the number of positive coefficients and the number of negative coefficients both are greater than or equal to 2 In this case, we will find a maximum and minimum from positive elements and from negative elements also and we will check -(maxPos)/(minPos) is smaller or -( abs(maxNeg) )/ ( abs(minNeg) ) is smaller and print the answer after swapping accordingly.Case #2: when the number of positive coefficients is greater than equal to 2 but the number of negative coefficients is less than 2 In this case, we will consider the case of the maximum of positive and minimum of positive elements only. Because if we picked up one from positive elements and the other from negative elements the result of -b/a will be a positive value which is not minimum. (as we require a large negative value) Case #3: when the number of negative coefficients is greater than equal to 2 but the number of positive coefficients is less than 2 In this case, we will consider the case of the maximum of negative and minimum of negative elements only. Because if we picked up one from positive elements and the other from negative elements the result of -b/a will be a positive value which is not minimum. (as we require a large negative value)Case #4: When both the counts are less than or equal to 1 Observe carefully, You cannot swap elements in this case. 
C++
Java
Python3
C#
Javascript
// C++ program to find minimum sum of roots of a// given polynomial#include <bits/stdc++.h>using namespace std; void getMinimumSum(int arr[], int n){    // resultant vector    vector<int> res;     // a vector that store indices of the positive    // elements    vector<int> pos;     // a vector that store indices of the negative    // elements    vector<int> neg;     for (int i = 0; i < n; i++) {        if (arr[i] > 0)            pos.push_back(i);               else if (arr[i] < 0)            neg.push_back(i);           }     // Case - 1:    if (pos.size() >= 2 && neg.size() >= 2) {        int posMax = INT_MIN, posMaxIdx = -1;        int posMin = INT_MAX, posMinIdx = -1;         int negMax = INT_MIN, negMaxIdx = -1;        int negMin = INT_MAX, negMinIdx = -1;         for (int i = 0; i < pos.size(); i++) {            if (arr[pos[i]] > posMax) {                posMaxIdx = pos[i];                posMax = arr[posMaxIdx];            }        }         for (int i = 0; i < pos.size(); i++) {            if (arr[pos[i]] < posMin &&                pos[i] != posMaxIdx) {                posMinIdx = pos[i];                posMin = arr[posMinIdx];            }        }         for (int i = 0; i < neg.size(); i++) {            if (abs(arr[neg[i]]) > negMax) {                negMaxIdx = neg[i];                negMax = abs(arr[negMaxIdx]);            }        }         for (int i = 0; i < neg.size(); i++) {            if (abs(arr[neg[i]]) < negMin &&                neg[i] != negMaxIdx) {                negMinIdx = neg[i];                negMin = abs(arr[negMinIdx]);            }        }         double posVal = -1.0 * (double)posMax / (double)posMin;        double negVal = -1.0 * (double)negMax / (double)negMin;         if (posVal < negVal) {            res.push_back(arr[posMinIdx]);            res.push_back(arr[posMaxIdx]);             for (int i = 0; i < n; i++) {                if (i != posMinIdx && i != posMaxIdx) {                    res.push_back(arr[i]);                }            }        }        else {            res.push_back(arr[negMinIdx]);            res.push_back(arr[negMaxIdx]);             for (int i = 0; i < n; i++) {                if (i != negMinIdx && i != negMaxIdx) {                    res.push_back(arr[i]);                }            }        }        for (int i = 0; i < res.size(); i++) {            cout << res[i] << " ";        }        cout << "\n";    }     // Case - 2:    else if (pos.size() >= 2) {        int posMax = INT_MIN, posMaxIdx = -1;        int posMin = INT_MAX, posMinIdx = -1;         for (int i = 0; i < pos.size(); i++) {            if (arr[pos[i]] > posMax) {                posMaxIdx = pos[i];                posMax = arr[posMaxIdx];            }        }         for (int i = 0; i < pos.size(); i++) {            if (arr[pos[i]] < posMin &&                pos[i] != posMaxIdx) {                posMinIdx = pos[i];                posMin = arr[posMinIdx];            }        }         res.push_back(arr[posMinIdx]);        res.push_back(arr[posMaxIdx]);         for (int i = 0; i < n; i++) {            if (i != posMinIdx && i != posMaxIdx) {                res.push_back(arr[i]);            }        }        for (int i = 0; i < res.size(); i++) {            cout << res[i] << " ";        }        cout << "\n";    }     // Case - 3:    else if (neg.size() >= 2) {        int negMax = INT_MIN, negMaxIdx = -1;        int negMin = INT_MAX, negMinIdx = -1;         for (int i = 0; i < neg.size(); i++) {            if (abs(arr[neg[i]]) > negMax) {                negMaxIdx = neg[i];                negMax = abs(arr[negMaxIdx]);            }        }         for (int i = 0; i < neg.size(); i++) {            if (abs(arr[neg[i]]) < negMin &&                neg[i] != negMaxIdx) {                negMinIdx = neg[i];                negMin = abs(arr[negMinIdx]);            }        }         res.push_back(arr[negMinIdx]);        res.push_back(arr[negMaxIdx]);         for (int i = 0; i < n; i++)            if (i != negMinIdx && i != negMaxIdx)                res.push_back(arr[i]);         for (int i = 0; i < res.size(); i++)            cout << res[i] << " ";                 cout << "\n";    }     // Case - 4:    else {        cout << "No swap required\n";    }} int main(){    int arr[] = { -4, 1, 6, -3, -2, -1 };    int n = sizeof(arr) / sizeof(arr[0]);    getMinimumSum(arr, n);    return 0;}
// Java  program to find minimum sum of roots of a// given polynomialimport java.io.*;import java.util.*; class GFG{     static void getMinimumSum(int arr[], int n)  {     // resultant vector    ArrayList<Integer> res = new ArrayList<Integer>();     // a vector that store indices of the positive    // elements    ArrayList<Integer> pos = new ArrayList<Integer>();     // a vector that store indices of the negative    // elements    ArrayList<Integer> neg = new ArrayList<Integer>();     for (int i = 0; i < n; i++)    {      if (arr[i] > 0)        pos.add(i);             else if (arr[i] < 0)        neg.add(i);           }     // Case - 1:    if (pos.size() >= 2 && neg.size() >= 2) {      int posMax = Integer.MIN_VALUE, posMaxIdx = -1;      int posMin = Integer.MAX_VALUE, posMinIdx = -1;       int negMax = Integer.MIN_VALUE, negMaxIdx = -1;      int negMin = Integer.MAX_VALUE, negMinIdx = -1;       for (int i = 0; i < pos.size(); i++) {        if (arr[pos.get(i)] > posMax) {          posMaxIdx = pos.get(i);          posMax = arr[posMaxIdx];        }      }       for (int i = 0; i < pos.size(); i++) {        if (arr[pos.get(i)] < posMin &&            pos.get(i) != posMaxIdx) {          posMinIdx = pos.get(i);          posMin = arr[posMinIdx];        }      }       for (int i = 0; i < neg.size(); i++) {        if (Math.abs(arr[neg.get(i)]) > negMax) {          negMaxIdx = neg.get(i);          negMax = Math.abs(arr[negMaxIdx]);        }      }       for (int i = 0; i < neg.size(); i++) {        if (Math.abs(arr[neg.get(i)]) < negMin &&            neg.get(i) != negMaxIdx) {          negMinIdx = neg.get(i);          negMin = Math.abs(arr[negMinIdx]);        }      }       double posVal = -1.0 * (double)posMax / (double)posMin;      double negVal = -1.0 * (double)negMax / (double)negMin;       if (posVal < negVal) {        res.add(arr[posMinIdx]);        res.add(arr[posMaxIdx]);         for (int i = 0; i < n; i++) {          if (i != posMinIdx && i != posMaxIdx) {            res.add(arr[i]);          }        }      }      else {        res.add(arr[negMinIdx]);        res.add(arr[negMaxIdx]);         for (int i = 0; i < n; i++) {          if (i != negMinIdx && i != negMaxIdx) {            res.add(arr[i]);          }        }      }      for (int i = 0; i < res.size(); i++) {        System.out.print(res.get(i) + " ");       }      System.out.println();     }     // Case - 2:    else if (pos.size() >= 2) {      int posMax = Integer.MIN_VALUE, posMaxIdx = -1;      int posMin = Integer.MAX_VALUE, posMinIdx = -1;       for (int i = 0; i < pos.size(); i++) {        if (arr[pos.get(i)] > posMax) {          posMaxIdx = pos.get(i);          posMax = arr[posMaxIdx];        }      }       for (int i = 0; i < pos.size(); i++) {        if (arr[pos.get(i)] < posMin &&            pos.get(i) != posMaxIdx) {          posMinIdx = pos.get(i);          posMin = arr[posMinIdx];        }      }       res.add(arr[posMinIdx]);      res.add(arr[posMaxIdx]);       for (int i = 0; i < n; i++) {        if (i != posMinIdx && i != posMaxIdx) {          res.add(arr[i]);        }      }      for (int i = 0; i < res.size(); i++) {        System.out.print(res.get(i)+" ");       }      System.out.println();     }     // Case - 3:    else if (neg.size() >= 2) {      int negMax = Integer.MIN_VALUE, negMaxIdx = -1;      int negMin = Integer.MAX_VALUE, negMinIdx = -1;       for (int i = 0; i < neg.size(); i++) {        if (Math.abs(arr[neg.get(i)]) > negMax) {          negMaxIdx = neg.get(i);          negMax = Math.abs(arr[negMaxIdx]);        }      }       for (int i = 0; i < neg.size(); i++) {        if (Math.abs(arr[neg.get(i)]) < negMin &&            neg.get(i) != negMaxIdx) {          negMinIdx = neg.get(i);          negMin = Math.abs(arr[negMinIdx]);        }      }       res.add(arr[negMinIdx]);      res.add(arr[negMaxIdx]);       for (int i = 0; i < n; i++)        if (i != negMinIdx && i != negMaxIdx)          res.add(arr[i]);       for (int i = 0; i < res.size(); i++)        System.out.println(res.get(i)+" ");       System.out.println();     }     // Case - 4:    else {      System.out.println("No swap required");     }  }   // Driver code  public static void main (String[] args)  {    int arr[] = { -4, 1, 6, -3, -2, -1 };    int n = arr.length;    getMinimumSum(arr, n);  }} // This code is contributed by rag2127
# Python3 program to find# minimum sum of roots of a# given polynomialimport sys def getMinimumSum(arr, n):     # resultant list    res = []     # a lis that store indices    # of the positive    # elements    pos = []     # a list that store indices    # of the negative    # elements    neg = []     for i in range(n):        if (arr[i] > 0):            pos.append(i)        elif (arr[i] < 0):            neg.append(i)     # Case - 1:    if (len(pos) >= 2 and        len(neg) >= 2):        posMax = -sys.maxsize-1        posMaxIdx = -1        posMin = sys.maxsize        posMinIdx = -1        negMax = -sys.maxsize-1        negMaxIdx = -1        negMin = sys.maxsize        negMinIdx = -1         for i in range(len(pos)):            if (arr[pos[i]] > posMax):                posMaxIdx = pos[i]                posMax = arr[posMaxIdx]         for i in range(len(pos)):            if (arr[pos[i]] < posMin and                    pos[i] != posMaxIdx):                posMinIdx = pos[i]                posMin = arr[posMinIdx]         for i in range(len(neg)):            if (abs(arr[neg[i]]) > negMax):                negMaxIdx = neg[i]                negMax = abs(arr[negMaxIdx])         for i in range(len(neg)):            if (abs(arr[neg[i]]) < negMin and                    neg[i] != negMaxIdx):                negMinIdx = neg[i]                negMin = abs(arr[negMinIdx])         posVal = (-1.0 * posMax /                         posMin)        negVal = (-1.0 * negMax /                         negMin)         if (posVal < negVal):            res.append(arr[posMinIdx])            res.append(arr[posMaxIdx])             for i in range(n):                if (i != posMinIdx and                    i != posMaxIdx):                    res.append(arr[i])        else:            res.append(arr[negMinIdx])            res.append(arr[negMaxIdx])             for i in range(n):                if (i != negMinIdx and                    i != negMaxIdx):                    resal.append(arr[i])         for i in range(len(res)):            print(res[i], end = " ")         print()     # Case - 2:    elif (len(pos) >= 2):        posMax = -sys.maxsize        posMaxIdx = -1        posMin = sys.maxsize        posMinIdx = -1         for i in range(len(pos)):            if (arr[pos[i]] > posMax):                posMaxIdx = pos[i]                posMax = arr[posMaxIdx]         for i in range(len(pos)):            if (arr[pos[i]] < posMin and                    pos[i] != posMaxIdx):                posMinIdx = pos[i]                posMin = arr[posMinIdx]         res.append(arr[posMinIdx])        res.append(arr[posMaxIdx])         for i in range(n):            if (i != posMinIdx and                i != posMaxIdx):                res.append(arr[i])         for i in range(len(res)):            print(res[i], end = " ")         print()     # Case - 3:    elif (len(neg) >= 2):        negMax = -sys.maxsize        negMaxIdx = -1        negMin = sys.maxsize        negMinIdx = -1         for i in range(len(neg)):            if (abs(arr[neg[i]]) > negMax):                negMaxIdx = neg[i]                negMax = abs(arr[negMaxIdx])         for i in range(len(neg)):            if (abs(arr[neg[i]]) < negMin and                    neg[i] != negMaxIdx):                negMinIdx = neg[i]                negMin = abs(arr[negMinIdx])         res.append(arr[negMinIdx])        res.append(arr[negMaxIdx])         for i in range(n):            if (i != negMinIdx and                i != negMaxIdx):                res.append(arr[i])         for i in range(len(res)):            print(res[i], end = " ")         print()     # Case - 4:    else:        print("No swap required") # Driver codeif __name__ == "__main__":     arr = [-4, 1, 6,           -3, -2, -1]    n = len(arr)    getMinimumSum(arr, n) # This code is contributed by Chitranayal
// C# program to find minimum sum of// roots of a given polynomialusing System;using System.Collections.Generic; class GFG{     static void getMinimumSum(int[] arr, int n){     // resultant vector    List<int> res = new List<int>();         // a vector that store indices of the positive    // elements    List<int> pos = new List<int>();         // a vector that store indices of the negative    // elements    List<int> neg = new List<int>();         for(int i = 0; i < n; i++)    {        if (arr[i] > 0)            pos.Add(i);               else if (arr[i] < 0)            neg.Add(i);           }         // Case - 1:    if (pos.Count >= 2 && neg.Count >= 2)    {        int posMax = Int32.MinValue, posMaxIdx = -1;        int posMin = Int32.MaxValue, posMinIdx = -1;                 int negMax = Int32.MinValue, negMaxIdx = -1;        int negMin = Int32.MaxValue, negMinIdx = -1;                 for(int i = 0; i < pos.Count; i++)        {            if (arr[pos[i]] > posMax)            {                posMaxIdx = pos[i];                posMax = arr[posMaxIdx];            }        }                 for(int i = 0; i < pos.Count; i++)        {            if (arr[pos[i]] < posMin &&                pos[i] != posMaxIdx)            {                posMinIdx = pos[i];                posMin = arr[posMinIdx];            }        }             for(int i = 0; i < neg.Count; i++)        {            if (Math.Abs(arr[neg[i]]) > negMax)            {                negMaxIdx = neg[i];                negMax = Math.Abs(arr[negMaxIdx]);            }        }             for(int i = 0; i < neg.Count; i++)        {            if (Math.Abs(arr[neg[i]]) < negMin &&                             neg[i] != negMaxIdx)            {                negMinIdx = neg[i];                negMin = Math.Abs(arr[negMinIdx]);            }        }             double posVal = -1.0 * (double)posMax / (double)posMin;        double negVal = -1.0 * (double)negMax / (double)negMin;                 if (posVal < negVal)        {            res.Add(arr[posMinIdx]);            res.Add(arr[posMaxIdx]);                         for(int i = 0; i < n; i++)            {                if (i != posMinIdx && i != posMaxIdx)                {                    res.Add(arr[i]);                }            }        }        else        {            res.Add(arr[negMinIdx]);            res.Add(arr[negMaxIdx]);                         for(int i = 0; i < n; i++)            {                if (i != negMinIdx && i != negMaxIdx)                {                    res.Add(arr[i]);                }            }        }        for(int i = 0; i < res.Count; i++)        {            Console.Write(res[i] + " ");        }        Console.WriteLine();    }         // Case - 2:    else if (pos.Count >= 2)    {        int posMax = Int32.MinValue, posMaxIdx = -1;        int posMin = Int32.MaxValue, posMinIdx = -1;                 for(int i = 0; i < pos.Count; i++)        {            if (arr[pos[i]] > posMax)            {                posMaxIdx = pos[i];                posMax = arr[posMaxIdx];            }        }                 for(int i = 0; i < pos.Count; i++)        {            if (arr[pos[i]] < posMin &&                    pos[i] != posMaxIdx)            {                posMinIdx = pos[i];                posMin = arr[posMinIdx];            }        }                 res.Add(arr[posMinIdx]);        res.Add(arr[posMaxIdx]);             for(int i = 0; i < n; i++)        {            if (i != posMinIdx && i != posMaxIdx)            {                res.Add(arr[i]);            }        }        for(int i = 0; i < res.Count; i++)        {            Console.Write(res[i] + " ");        }        Console.WriteLine();    }         // Case - 3:    else if (neg.Count >= 2)    {        int negMax = Int32.MinValue, negMaxIdx = -1;        int negMin = Int32.MaxValue, negMinIdx = -1;                 for(int i = 0; i < neg.Count; i++)        {            if (Math.Abs(arr[neg[i]]) > negMax)            {                negMaxIdx = neg[i];                negMax = Math.Abs(arr[negMaxIdx]);            }        }                 for(int i = 0; i < neg.Count; i++)        {            if (Math.Abs(arr[neg[i]]) < negMin &&                             neg[i] != negMaxIdx)            {                negMinIdx = neg[i];                negMin = Math.Abs(arr[negMinIdx]);            }        }                 res.Add(arr[negMinIdx]);        res.Add(arr[negMaxIdx]);                 for(int i = 0; i < n; i++)            if (i != negMinIdx && i != negMaxIdx)                res.Add(arr[i]);                 for(int i = 0; i < res.Count; i++)            Console.WriteLine(res[i] + " ");                 Console.WriteLine();    }         // Case - 4:    else    {        Console.WriteLine("No swap required");    }} // Driver codestatic public void Main(){    int[] arr = { -4, 1, 6, -3, -2, -1 };    int n = arr.Length;         getMinimumSum(arr, n);}} // This code is contributed by avanitrachhadiya2155
<script>// Javascript  program to find minimum sum of roots of a// given polynomial function getMinimumSum(arr,n){    // resultant vector    let res = [] ;      // a vector that store indices of the positive    // elements    let pos = [] ;      // a vector that store indices of the negative    // elements    let neg = [];      for (let i = 0; i < n; i++)    {      if (arr[i] > 0)        pos.push(i);            else if (arr[i] < 0)        neg.push(i);          }      // Case - 1:    if (pos.length >= 2 && neg.length >= 2) {      let posMax = Number.MIN_VALUE, posMaxIdx = -1;      let posMin = Number.MAX_VALUE, posMinIdx = -1;        let negMax = Number.MIN_VALUE, negMaxIdx = -1;      let negMin = Number.MAX_VALUE, negMinIdx = -1;        for (let i = 0; i < pos.length; i++) {        if (arr[pos[i]] > posMax) {          posMaxIdx = pos[i];          posMax = arr[posMaxIdx];        }      }        for (let i = 0; i < pos.length; i++) {        if (arr[pos[i]] < posMin &&            pos[i] != posMaxIdx) {          posMinIdx = pos[i];          posMin = arr[posMinIdx];        }      }        for (let i = 0; i < neg.length; i++) {        if (Math.abs(arr[neg[i]]) > negMax) {          negMaxIdx = neg[i];          negMax = Math.abs(arr[negMaxIdx]);        }      }        for (let i = 0; i < neg.length; i++) {        if (Math.abs(arr[neg[i]]) < negMin &&            neg[i] != negMaxIdx) {          negMinIdx = neg[i];          negMin = Math.abs(arr[negMinIdx]);        }      }        let posVal = -1.0 * posMax / posMin;      let negVal = -1.0 * negMax / negMin;        if (posVal < negVal) {        res.push(arr[posMinIdx]);        res.push(arr[posMaxIdx]);          for (let i = 0; i < n; i++) {          if (i != posMinIdx && i != posMaxIdx) {            res.push(arr[i]);          }        }      }      else {        res.push(arr[negMinIdx]);        res.push(arr[negMaxIdx]);          for (let i = 0; i < n; i++) {          if (i != negMinIdx && i != negMaxIdx) {            res.push(arr[i]);          }        }      }      for (let i = 0; i < res.length; i++) {        document.write(res[i] + " ");        }      document.write("<br>");      }      // Case - 2:    else if (pos.length >= 2) {      let posMax = Number.MIN_VALUE, posMaxIdx = -1;      let posMin = Number.MAX_VALUE, posMinIdx = -1;        for (let i = 0; i < pos.length; i++) {        if (arr[pos[i]] > posMax) {          posMaxIdx = pos[i];          posMax = arr[posMaxIdx];        }      }        for (let i = 0; i < pos.length; i++) {        if (arr[pos[i]] < posMin &&            pos[i] != posMaxIdx) {          posMinIdx = pos[i];          posMin = arr[posMinIdx];        }      }        res.push(arr[posMinIdx]);      res.push(arr[posMaxIdx]);        for (let i = 0; i < n; i++) {        if (i != posMinIdx && i != posMaxIdx) {          res.push(arr[i]);        }      }      for (let i = 0; i < res.length; i++) {        document.write(res[i]+" ");        }      document.write("<br>");      }      // Case - 3:    else if (neg.length >= 2) {      let negMax = Number.MIN_VALUE, negMaxIdx = -1;      let negMin = Number.MAX_VALUE, negMinIdx = -1;        for (let i = 0; i < neg.length; i++) {        if (Math.abs(arr[neg[i]]) > negMax) {          negMaxIdx = neg[i];          negMax = Math.abs(arr[negMaxIdx]);        }      }        for (let i = 0; i < neg.length; i++) {        if (Math.abs(arr[neg[i]]) < negMin &&            neg[i] != negMaxIdx) {          negMinIdx = neg[i];          negMin = Math.abs(arr[negMinIdx]);        }      }        res.push(arr[negMinIdx]);      res.push(arr[negMaxIdx]);        for (let i = 0; i < n; i++)        if (i != negMinIdx && i != negMaxIdx)          res.push(arr[i]);        for (let i = 0; i < res.length; i++)        document.write(res[i]+" ");        document.write("<br>");      }      // Case - 4:    else {      document.write("No swap required");      }         } // Driver codelet arr=[-4, 1, 6, -3, -2, -1];let n = arr.length;getMinimumSum(arr, n);              // This code is contributed by unknown2108</script>
1 6 -4 -3 -2 -1
 
ukasp
rag2127
avanitrachhadiya2155
unknown2108
surinderdawra388
maths-polynomial
Arrays
Searching
Arrays
Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count pairs with given sum
Chocolate Distribution Problem
Window Sliding Technique
Reversal algorithm for array rotation
Next Greater Element
Binary Search
Median of two sorted arrays of different sizes
Find the index of an array element in Java
Two Pointers Technique
Count number of occurrences (or frequency) in a sorted array