Adding elements of an array until every element becomes greater than or equal to k - GeeksforGeeks

06 Jul, 2021
We are given a list of N unsorted elements, we need to find minimum number of steps in which the elements of the list can be added to make all the elements greater than or equal to K. We are allowed to add two elements together and make them one.Examples:  
Input : arr[] = {1 10 12 9 2 3}
          K = 6
Output : 2
First we add (1 + 2), now the new list becomes 
3 10 12 9 3, then we add (3 + 3),  now the new 
list becomes 6 10 12 9, Now all the elements in 
the list are greater than 6. Hence the output is 
2 i:e 2 operations are required 
to do this.
 
As we can see from above explanation, we need to extract two smallest elements and then add their sum to list. We need to continue this step until all elements are greater than or equal to K.Method 1 (Brute Force): We can create a simple array the sort it and then add two minimum elements and keep on storing them back in the array until all the elements become greater than K.Method 2 (Efficient): If we take a closer look, we can notice that this problem is similar to Huffman coding. We use Min Heap as the main operations here are extract min and insert. Both of these operations can be done in O(Log n) time.  
C++
Java
C#
Javascript
// A C++ program to count minimum steps to make all// elements greater than or equal to k.#include<bits/stdc++.h>using namespace std; // A class for Min Heapclass MinHeap{    int *harr;    int capacity; // maximum size    int heap_size; // Current countpublic:    // Constructor    MinHeap(int *arr, int capacity);     // to heapify a subtree with root at    // given index    void heapify(int );     int parent(int i)    {        return (i-1)/2;    }     // to get index of left child of    // node at index i    int left(int i)    {        return (2*i + 1);    }     // to get index of right child of    // node at index i    int right(int i)    {        return (2*i + 2);    }     // to extract the root which is the    // minimum element    int extractMin();     // Returns the minimum key (key at    // root) from min heap    int getMin()    {        return harr[0];    }     int getSize()    {        return heap_size;    }     // Inserts a new key 'k'    void insertKey(int k);}; // Constructor: Builds a heap from// a given array a[] of given sizeMinHeap::MinHeap(int arr[], int n){    heap_size = n;    capacity = n;    harr = new int[n];     for (int i=0; i<n; i++)        harr[i] = arr[i];     // building the heap from first    // non-leaf node by calling max    // heapify function    for (int i=n/2-1; i>=0; i--)        heapify(i);} // Inserts a new key 'k'void MinHeap::insertKey(int k){    // First insert the new key at the end    heap_size++;    int i = heap_size - 1;    harr[i] = k;     // Fix the min heap property if it is violated    while (i != 0 && harr[parent(i)] > harr[i])    {        swap(harr[i], harr[parent(i)]);        i = parent(i);    }} // Method to remove minimum element// (or root) from min heapint MinHeap::extractMin(){    if (heap_size <= 0)        return INT_MAX;    if (heap_size == 1)    {        heap_size--;        return harr[0];    }     // Store the minimum value, and    // remove it from heap    int root = harr[0];    harr[0] = harr[heap_size-1];    heap_size--;    heapify(0);     return root;} // A recursive method to heapify a subtree// with root at given index. This method// assumes that the subtrees are already// heapifiedvoid MinHeap::heapify(int i){    int l = left(i);    int r = right(i);    int smallest = i;    if (l < heap_size && harr[l] < harr[i])        smallest = l;    if (r < heap_size && harr[r] < harr[smallest])        smallest = r;    if (smallest != i)    {        swap(harr[i], harr[smallest]);        heapify(smallest);    }} // Returns count of steps needed to make// all elements greater than or equal to// k by adding elementsint countMinOps(int arr[], int n, int k){    // Build a min heap of array elements    MinHeap h(arr, n);     long int res = 0;     while (h.getMin() < k)    {        if (h.getSize() == 1)            return -1;         // Extract two minimum elements        // and insert their sum        int first = h.extractMin();        int second = h.extractMin();        h.insertKey(first + second);         res++;    }     return res;} // Driver codeint main(){    int arr[] = {1, 10, 12, 9, 2, 3};    int n  = sizeof(arr)/sizeof(arr[0]);    int k = 6;    cout << countMinOps(arr, n, k);    return 0;}
// A Java program to count minimum steps to make all// elements greater than or equal to k.public class Add_Elements {          // A class for Min Heap    static class MinHeap    {        int[] harr;        int capacity; // maximum size        int heap_size; // Current count             // Constructor: Builds a heap from        // a given array a[] of given size        MinHeap(int arr[], int n)        {            heap_size = n;            capacity = n;            harr = new int[n];                      for (int i=0; i<n; i++)                harr[i] = arr[i];                      // building the heap from first            // non-leaf node by calling max            // heapify function            for (int i=n/2-1; i>=0; i--)                heapify(i);        }              // A recursive method to heapify a subtree        // with root at given index. This method        // assumes that the subtrees are already        // heapified        void heapify(int i)        {            int l = left(i);            int r = right(i);            int smallest = i;            if (l < heap_size && harr[l] < harr[i])                smallest = l;            if (r < heap_size && harr[r] < harr[smallest])                smallest = r;            if (smallest != i)            {                int temp = harr[i];                harr[i] = harr[smallest];                harr[smallest] = temp;                heapify(smallest);            }        }              static int parent(int i)        {            return (i-1)/2;        }              // to get index of left child of        // node at index i        static int left(int i)        {            return (2*i + 1);        }              // to get index of right child of        // node at index i        int right(int i)        {            return (2*i + 2);        }              // Method to remove minimum element        // (or root) from min heap        int extractMin()        {            if (heap_size <= 0)                return Integer.MAX_VALUE;            if (heap_size == 1)            {                heap_size--;                return harr[0];            }                      // Store the minimum value, and            // remove it from heap            int root = harr[0];            harr[0] = harr[heap_size-1];            heap_size--;            heapify(0);                      return root;        }              // Returns the minimum key (key at        // root) from min heap        int getMin()        {            return harr[0];        }              int getSize()        {            return heap_size;        }              // Inserts a new key 'k'        void insertKey(int k)        {            // First insert the new key at the end            heap_size++;            int i = heap_size - 1;            harr[i] = k;                      // Fix the min heap property if it is violated            while (i != 0 && harr[parent(i)] > harr[i])            {                 int temp = harr[i];                 harr[i] = harr[parent(i)];                 harr[parent(i)] = temp;                 i = parent(i);            }        }    }                // Returns count of steps needed to make    // all elements greater than or equal to    // k by adding elements    static int countMinOps(int arr[], int n, int k)    {        // Build a min heap of array elements        MinHeap h = new MinHeap(arr, n);              int res = 0;              while (h.getMin() < k)        {            if (h.getSize() == 1)                return -1;                  // Extract two minimum elements            // and insert their sum            int first = h.extractMin();            int second = h.extractMin();            h.insertKey(first + second);                  res++;        }              return res;    }          // Driver code    public static void main(String args[])    {        int arr[] = {1, 10, 12, 9, 2, 3};        int n  = arr.length;        int k = 6;        System.out.println(countMinOps(arr, n, k));    }}// This code is contributed by Sumit Ghosh
// A C# program to count minimum steps to make all// elements greater than or equal to k.using System;     public class Add_Elements{         // A class for Min Heap    public class MinHeap    {        public int[] harr;        public int capacity; // maximum size        public int heap_size; // Current count             // Constructor: Builds a heap from        // a given array a[] of given size        public MinHeap(int []arr, int n)        {            heap_size = n;            capacity = n;            harr = new int[n];                     for (int i = 0; i < n; i++)                harr[i] = arr[i];                     // building the heap from first            // non-leaf node by calling max            // heapify function            for (int i = n/2-1; i >= 0; i--)                heapify(i);        }             // A recursive method to heapify a subtree        // with root at given index. This method        // assumes that the subtrees are already        // heapified        public void heapify(int i)        {            int l = left(i);            int r = right(i);            int smallest = i;            if (l < heap_size && harr[l] < harr[i])                smallest = l;            if (r < heap_size && harr[r] < harr[smallest])                smallest = r;            if (smallest != i)            {                int temp = harr[i];                harr[i] = harr[smallest];                harr[smallest] = temp;                heapify(smallest);            }        }             public static int parent(int i)        {            return (i-1)/2;        }             // to get index of left child of        // node at index i        static int left(int i)        {            return (2*i + 1);        }             // to get index of right child of        // node at index i        public int right(int i)        {            return (2*i + 2);        }             // Method to remove minimum element        // (or root) from min heap        public int extractMin()        {            if (heap_size <= 0)                return int.MaxValue;            if (heap_size == 1)            {                heap_size--;                return harr[0];            }                     // Store the minimum value, and            // remove it from heap            int root = harr[0];            harr[0] = harr[heap_size-1];            heap_size--;            heapify(0);                     return root;        }             // Returns the minimum key (key at        // root) from min heap        public int getMin()        {            return harr[0];        }             public int getSize()        {            return heap_size;        }             // Inserts a new key 'k'        public void insertKey(int k)        {            // First insert the new key at the end            heap_size++;            int i = heap_size - 1;            harr[i] = k;                     // Fix the min heap property if it is violated            while (i != 0 && harr[parent(i)] > harr[i])            {                int temp = harr[i];                harr[i] = harr[parent(i)];                harr[parent(i)] = temp;                i = parent(i);            }        }    }              // Returns count of steps needed to make    // all elements greater than or equal to    // k by adding elements    static int countMinOps(int []arr, int n, int k)    {        // Build a min heap of array elements        MinHeap h = new MinHeap(arr, n);             int res = 0;             while (h.getMin() < k)        {            if (h.getSize() == 1)                return -1;                 // Extract two minimum elements            // and insert their sum            int first = h.extractMin();            int second = h.extractMin();            h.insertKey(first + second);                 res++;        }             return res;    }         // Driver code    public static void Main(String []args)    {        int []arr = {1, 10, 12, 9, 2, 3};        int n = arr.Length;        int k = 6;        Console.WriteLine(countMinOps(arr, n, k));    }} // This code has been contributed by 29AjayKumar
<script> // A JavaScript program to count minimum steps to make all// elements greater than or equal to k. let harr;let capacity; // maximum sizelet heap_size; // Current count // Constructor: Builds a heap from        // a given array a[] of given sizefunction MinHeap(arr,n){    heap_size = n;            capacity = n;            harr = new Array(n);                        for (let i=0; i<n; i++)                harr[i] = arr[i];                        // building the heap from first            // non-leaf node by calling max            // heapify function            for (let i=n/2-1; i>=0; i--)                heapify(i);} // A recursive method to heapify a subtree        // with root at given index. This method        // assumes that the subtrees are already        // heapifiedfunction heapify(i){    let l = left(i);            let r = right(i);            let smallest = i;            if (l < heap_size && harr[l] < harr[i])                smallest = l;            if (r < heap_size && harr[r] < harr[smallest])                smallest = r;            if (smallest != i)            {                let temp = harr[i];                harr[i] = harr[smallest];                harr[smallest] = temp;                heapify(smallest);            }} function parent(i){    return (i-1)/2;} // to get index of left child of        // node at index ifunction left(i){    return (2*i + 1);} // to get index of right child of        // node at index ifunction right(i){    return (2*i + 2);} // Method to remove minimum element        // (or root) from min heapfunction extractMin(){    if (heap_size <= 0)                return Number.MAX_VALUE;            if (heap_size == 1)            {                heap_size--;                return harr[0];            }                        // Store the minimum value, and            // remove it from heap            let root = harr[0];            harr[0] = harr[heap_size-1];            heap_size--;            heapify(0);                        return root;} // Returns the minimum key (key at        // root) from min heapfunction getMin(){    return harr[0];} function getSize(){    return heap_size;} // Inserts a new key 'k'function insertKey(k){    // First insert the new key at the end            heap_size++;            let i = heap_size - 1;            harr[i] = k;                        // Fix the min heap property if it is violated            while (i != 0 && harr[parent(i)] > harr[i])            {                 let temp = harr[i];                 harr[i] = harr[parent(i)];                 harr[parent(i)] = temp;                 i = parent(i);            }} // Returns count of steps needed to make    // all elements greater than or equal to    // k by adding elementsfunction countMinOps(arr,n,k){    // Build a min heap of array elements        MinHeap(arr, n);                let res = 0;                while (getMin() < k)        {            if (getSize() == 1)                return -1;                    // Extract two minimum elements            // and insert their sum            let first = extractMin();            let second = extractMin();            insertKey(first + second);                    res++;        }                return res;} // Driver codelet arr=[1, 10, 12, 9, 2, 3];let n  = arr.length;let  k = 6;document.write(countMinOps(arr, n, k));     // This code is contributed by rag2127 </script>
Output:  
2
This article is contributed by Sarthak Kohli. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
29AjayKumar
rag2127
Arrays
Heap
Arrays
Heap
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
HeapSort
Binary Heap
K'th Smallest/Largest Element in Unsorted Array | Set 1
k largest(or smallest) elements in an array
Building Heap from Array