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

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 Heap
class MinHeap
{
    int *harr;
    int capacity; // maximum size
    int heap_size; // Current count
public:
    // 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 size
MinHeap::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 heap
int 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
// heapified
void 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 elements
int 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 code
int 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right



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 contribute.geeksforgeeks.org or mail your article to contribute@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.



My Personal Notes arrow_drop_up

Improved By : 29AjayKumar



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.