Open In App

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

Last Updated : 25 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

We are given a list of N unsorted elements, we need to find the 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
Explanation: 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 the above explanation, we need to extract the two smallest elements and then add their sum to the 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 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 operation here is extracting min and inserting. Both of these operations can be done in O(Log n) time. 

Implementation:

C++




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


Java




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


C#




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


Javascript




<script>
 
// A JavaScript program to count minimum steps to make all
// elements greater than or equal to k.
 
let harr;
let capacity; // maximum size
let heap_size; // Current count
 
// Constructor: Builds a heap from
        // a given array a[] of given size
function 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
        // heapified
function 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 i
function left(i)
{
    return (2*i + 1);
}
 
// to get index of right child of
        // node at index i
function right(i)
{
    return (2*i + 2);
}
 
// Method to remove minimum element
        // (or root) from min heap
function 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 heap
function 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 elements
function 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 code
let 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>


Python3




# A Python program to count minimum steps to make all
# elements greater than or equal to k.
 
import heapq
 
# A class for Min Heap
 
 
class MinHeap:
    def __init__(self, arr):
        self.harr = arr[:]
        heapq.heapify(self.harr)
 
    # to extract the root which is the
    # minimum element
    def extractMin(self):
        return heapq.heappop(self.harr)
 
    # Returns the minimum key (key at
    # root) from min heap
    def getMin(self):
        return self.harr[0]
 
    def getSize(self):
        return len(self.harr)
 
    # Inserts a new key 'k'
    def insertKey(self, k):
        heapq.heappush(self.harr, k)
 
# Returns count of steps needed to make
# all elements greater than or equal to
# k by adding elements
 
 
def countMinOps(arr, n, k):
    # Build a min heap of array elements
    h = MinHeap(arr)
 
    res = 0
 
    while h.getMin() < k:
        if h.getSize() == 1:
            return -1
 
        # Extract two minimum elements
        # and insert their sum
        first = h.extractMin()
        second = h.extractMin()
        h.insertKey(first + second)
 
        res += 1
 
    return res
 
 
# Driver code
arr = [1, 10, 12, 9, 2, 3]
n = len(arr)
k = 6
print(countMinOps(arr, n, k))


Output

2

Time Complexity: O(n log(n)), where n is the length of the given array.
Auxiliary Space: O(n)

Approach using the inbuilt function: We can also solve the problem easily by using the inbuilt function ( min-heap )

Approach:

  1. Store all the array values in min_heap;
  2. Now run a while loop until the size of the priority queue becomes either equal to 1 or the top element present in the queue is greater than k. The latter part means that if the top element itself is greater than the k then all the elements present in the priority queue are greater than k.
  3. Each time you run the loop just increment the count which represents the number of times the operation has been performed.

Below is the implementation of the above approach:

C++




// A C++ program to count minimum steps to make all
// elements greater than or equal to k.
#include <bits/stdc++.h>
using namespace std;
 
int countMinOps(int arr[], int n, int k)
{
    priority_queue<int, vector<int>, greater<int> > pq;
    for (int i = 0; i < n; i++)
        pq.push(arr[i]);
    int count = 0;
    while (pq.size() > 1 && pq.top() < k) {
        int min1 = pq.top();
        pq.pop();
        int min2 = pq.top();
        pq.pop();
        int sum = min1 + min2;
        pq.push(sum);
        count++;
    }
    if (pq.top() < k)
        return -1;
    return count;
}
 
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;
}
 
// This code is contributed by Aditya Kumar (adityakumar129)


Java




// A Java program to count minimum steps to make all
// elements greater than or equal to k.
import java.util.*;
public class GFG {
 
    static int countMinOps(int arr[], int n, int k)
    {
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for (int i = 0; i < n; i++)
            pq.add(arr[i]);
        int count = 0;
        while (pq.size() > 1 && pq.peek() < k) {
            int min1 = pq.peek();
            pq.remove();
            int min2 = pq.peek();
            pq.remove();
            int sum = min1 + min2;
            pq.add(sum);
            count++;
        }
        if (pq.peek() < k)
            return -1;
        return count;
    }
    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 Karandeep1234


Python3




# A Python3 program to count minimum steps to make all
# elements greater than or equal to k.
import queue
 
def countMinOps(arr, n, k):
    pq = queue.PriorityQueue()
    for i in range(n):
        pq.put(arr[i])
    count = 0
    while (not pq.empty()) and pq.queue[0] < k:
        min1 = pq.get()
        min2 = pq.get()
        sum = min1 + min2
        pq.put(sum)
        count += 1
    if (not pq.empty()) and pq.queue[0] < k:
        return -1
    return count
 
arr = [1, 10, 12, 9, 2, 3]
n = len(arr)
k = 6
print(countMinOps(arr, n, k))


C#




using System;
using System.Collections.Generic;
 
public class Program
{
    static int CountMinOps(int[] arr, int n, int k)
    {
        SortedSet<int> set = new SortedSet<int>(arr);
        int count = 0;
        while (set.Count > 1 && set.Min < k)
        {
            int min1 = set.Min;
            set.Remove(min1);
            int min2 = set.Min;
            set.Remove(min2);
            int sum = min1 + min2;
            set.Add(sum);
            count++;
        }
        if (set.Min < k)
            return -1;
        return count;
    }
 
    public static void Main()
    {
        int[] arr = { 1, 10, 12, 9, 2, 3 };
        int n = arr.Length;
        int k = 6;
        Console.WriteLine(CountMinOps(arr, n, k));
    }
}


Javascript




// A JavaScript program to count minimum steps to make all
// elements greater than or equal to k.
function CountMinOps(arr, n, k) {
  let set = new Set(arr);
  let count = 0;
  while (set.size > 1 && Math.min(...set) < k) {
    let min1 = Math.min(...set);
    set.delete(min1);
    let min2 = Math.min(...set);
    set.delete(min2);
    let sum = min1 + min2;
    set.add(sum);
    count++;
  }
  if (Math.min(...set) < k) {
    return -1;
  }
  return count;
}
 
let arr = [1, 10, 12, 9, 2, 3];
let n = arr.length;
let k = 6;
console.log(CountMinOps(arr, n, k));


Output

2

Time Complexity: O(n log(n)), where n is the length of the given array.
Auxiliary Space: O(n)

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads