Open In App

Merge K minimum elements of the array until there is only one element

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] and an integer K, the task is to merge K minimum elements of the array until there is only one element left in the array.
Note: If it is impossible to merge into only one element then print -1. 
 

Input: arr[] = {3, 2, 4, 1}, K = 2 
Output: 10 
Explanation: 
Merge K minimum elements of the Array({3, 2, 4, 1}) = 1 + 2 = 3 
After Merging the Array will be {3, 3, 4} 
Merge K minimum elements of the Array ({3, 3, 4}) = 3 + 3 = 6 
After Merging the Array will be {4, 6} 
Merge K minimum elements of the Array ({4, 6}) = 4 + 6 = 10
Input: arr[] = {3, 2, 4, 1}, K = 3 
Output: -1 
Explanation: 
After merging there will be two elements left {6, 4} which cannot be merged further. 
 

 

Approach: The idea is to sort the array and then merge the first K minimum elements of the array into one element, then insert the element into the array at its sorted position into the array with the help of the Binary Search. Similarly, repeat this step until there is only one element left in the array. If in the end there are less than K elements left then return -1.
Below is the implementation of the above approach: 
 

C++




// C++ implementation to merge the K minimum elements of the
// array until there is only one element is left in the
// array
#include <bits/stdc++.h>
using namespace std;
 
class GFG {
public:
    // Utility function to insert the element at its correct
    // position in a sorted array (Binary search is used to
    // get the index of the correct position)
    void insertInSortedList(vector<int>& sortedList,
                            int item, int start, int end)
    {
        int mid = start + (end - start) / 2;
        if (mid == 0 || mid == end - 1
            || sortedList[mid] == item) {
            sortedList.insert(sortedList.begin() + mid,
                              item);
            return;
        }
        else if (sortedList[mid] < item) {
            insertInSortedList(sortedList, item, mid + 1,
                               end);
        }
        else {
            insertInSortedList(sortedList, item, start,
                               mid - 1);
        }
    }
 
    // Function to merge the element of the array until
    // there is only one element left in array
    int mergeStones(vector<int>& List, int k)
    {
        // Sort the array
        sort(List.begin(), List.end());
 
        int cost = 0;
 
        // Loop to merge the elements until there are
        // greater than K elements in the array
        while (List.size() > k) {
            int Sum = 0;
 
            // Obtain the sum of K minimum elements
            for (int i = 0; i < k; i++) {
                Sum += List[i];
            }
 
            // Remove the K minimum elements from the array
            for (int i = 0; i < k; i++) {
                List.erase(List.begin());
            }
 
            // Insert the merged element into the sorted
            // array at its correct position
            insertInSortedList(List, Sum, 0, List.size());
            cost += Sum;
        }
 
        // If there are only K elements left,
        // take the sum and return the sum, else return -1
        if (List.size() == k) {
            int temp = 0;
            for (int i = 0; i < k; i++) {
                temp += List[i];
            }
            cost += temp;
            return cost;
        }
        else {
            return -1;
        }
    }
};
 
// Driver code
int main()
{
    vector<int> stones;
    stones.push_back(3);
    stones.push_back(2);
    stones.push_back(4);
    stones.push_back(1);
    cout << GFG().mergeStones(stones, 3) << "\n";
    cout << GFG().mergeStones(stones, 2) << "\n";
    return 0;
}
 
// This code is contributed by akashish__


Java




// Java implementation to merge the
// K minimum elements of the Array
// until there is only one element
// is left in the array
 
// Imports
import java.io.*;
import java.lang.*;
import java.util.*;
 
 
class GFG {
     
    // Function to merge the element
    // of the array until there is
    // only one element left in array
    public static int mergeStones(
        List<Integer> list, final int k) {
         
        // Sorting the array
        Collections.sort(list);
        int cost = 0;
         
        // Loop to merge the elements
        // until there is element
        // greater than K elements
        while(list.size() > k) {
            int sum = 0;
             
            // Merging the K minimum
            // elements of the array
            for(int i = 0; i < k; i++) {
                sum += list.get(i);
            }
             
            // Removing the K minimum
            // elements of the array
            list.subList(0, k).clear();
             
            // Inserting the merged
            // element into the array
            insertInSortedList(list, sum);
            cost += sum;
        }
         
        // If there is only K element
        // left then return the element
        if(list.size() == k) {
            cost += list.stream().reduce(0, Integer::sum);
            return cost;
        } else {
            return -1;
        }
    }
     
    // Function insert the element into
    // the sorted position in the array
    public static void insertInSortedList(
        List<Integer> sortedList, int item) {
        int len = sortedList.size();
        insertInSortedList(sortedList, item,
                                 0, len - 1);
    }
     
    // Utility function to insert into the
    // array with the help of the position
    public static void insertInSortedList(
        List<Integer> sortedList, int item,
                       int start, int end) {
        int mid = (int) ((end - start)/ 2.00);
        if(mid == 0 ||
             (mid == sortedList.size() - 1) ||
                sortedList.get(mid) == item) {
            sortedList.add(mid, item);
            return;
        }
        else if(sortedList.get(mid) < item) {
            insertInSortedList(sortedList,
                       item, mid + 1, end);
        } else {
            insertInSortedList(sortedList,
                     item, start, mid - 1);
        }
    }
     
    // Driver Code
    public static void main(String [] args) {
        List<Integer> stones = new ArrayList<>();
        stones.add(3);
        stones.add(2);
        stones.add(4);
        stones.add(1);
        System.out.println(mergeStones(stones, 3));
        System.out.println(mergeStones(stones, 2));
    }
}


Python3




# Python implementation to merge the K minimum elements of the array
# until there is only one element is left in the array
class GFG:
 
    # Utility function to insert the element at its correct position in a sorted array
    # (Binary search is used to get the index of the correct position)
    def insertInSortedList(self, sortedList, item, start, end):
        mid = start + (end - start) // 2
        if mid == 0 or mid == end - 1 or sortedList[mid] == item:
            sortedList.insert(mid, item)
            return
        elif sortedList[mid] < item:
            self.insertInSortedList(sortedList, item, mid + 1, end)
        else:
            self.insertInSortedList(sortedList, item, start, mid - 1)
 
    # Function to merge the element of the array until there is
    # only one element left in array
    def mergeStones(self, List, k):
 
        # Sort the array
        List.sort()
 
        cost = 0
 
        # Loop to merge the elements until there are
        # greater than K elements in the array
        while len(List) > k:
            Sum = 0
 
            # Obtain the sum of K minimum elements
            for i in range(k):
                Sum += List[i]
 
            # Remove the K minimum elements from the array
            for _ in range(k):
                List.pop(0)
 
            # Insert the merged element into the sorted array
            # at its correct position
            self.insertInSortedList(List, Sum, 0, len(List))
            cost += Sum
 
        # If there are only K elements left,
        # take the sum and return the sum, else return -1
        if len(List) == k:
            cost += sum(List[:])
            return cost
        else:
            return -1
 
# Driver code
if __name__ == '__main__':
    stones = []
    stones.append(3)
    stones.append(2)
    stones.append(4)
    stones.append(1)
    print(GFG().mergeStones(stones, 3))
    print(GFG().mergeStones(stones, 2))
     
    # This code is contributed by keshavrathi


C#




// Include namespace system
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
 
public class GFG
{
   
  // Function to merge the element
  // of the array until there is
  // only one element left in array
  public static int mergeStones(List<int> list, int k)
  {
     
    // Sorting the array
    list.Sort();
    var cost = 0;
     
    // Loop to merge the elements
    // until there is element
    // greater than K elements
    while (list.Count > k)
    {
      var sum = 0;
       
      // Merging the K minimum
      // elements of the array
      for (int i = 0; i < k; i++)
      {
        sum += list[i];
      }
       
      // Removing the K minimum
      // elements of the array
      for(int t = 0; t < k; t++){
        list.RemoveAt(0);
      }
 
      // Inserting the merged
      // element into the array
      GFG.insertInSortedList(list, sum);
      cost += sum;
    }
     
    // If there is only K element
    // left then return the element
    if (list.Count == k)
    {
      cost += list.AsQueryable().Sum();
      return cost;
    }
    else
    {
      return -1;
    }
  }
   
  // Function insert the element into
  // the sorted position in the array
  public static void insertInSortedList(List<int> sortedList, int item)
  {
    var len = sortedList.Count;
    GFG.insertInSortedList(sortedList, item, 0, len - 1);
  }
   
  // Utility function to insert into the
  // array with the help of the position
  public static void insertInSortedList(List<int> sortedList, int item, int start, int end)
  {
    var mid = (int)((end - start) / 2.0);
    if (mid == 0 || (mid == sortedList.Count - 1) || sortedList[mid] == item)
    {
      sortedList.Insert(mid,item);
      return;
    }
    else if (sortedList[mid] < item)
    {
      GFG.insertInSortedList(sortedList, item, mid + 1, end);
    }
    else
    {
      GFG.insertInSortedList(sortedList, item, start, mid - 1);
    }
  }
   
  // Driver Code
  public static void Main(String[] args)
  {
    var stones = new List<int>();
    stones.Add(3);
    stones.Add(2);
    stones.Add(4);
    stones.Add(1);
    Console.WriteLine(GFG.mergeStones(stones, 3));
    Console.WriteLine(GFG.mergeStones(stones, 2));
  }
}
 
// This code is contributed by aadityaburujwale.


Javascript




// JavaScript implementation to merge the K minimum elements of the array
// until there is only one element is left in the array
class GFG
{
 
  // Utility function to insert the element at its correct position in a sorted array
  // (Binary search is used to get the index of the correct position)
  insertInSortedList(sortedList, item, start, end) {
    let mid = start + Math.floor((end - start) / 2);
    if (mid === 0 || mid === end - 1 || sortedList[mid] === item) {
      sortedList.splice(mid, 0, item);
      return;
    } else if (sortedList[mid] < item) {
      this.insertInSortedList(sortedList, item, mid + 1, end);
    } else {
      this.insertInSortedList(sortedList, item, start, mid - 1);
    }
  }
 
  // Function to merge the element of the array until there is
  // only one element left in array
  mergeStones(List, k)
  {
   
    // Sort the array
    List.sort((a, b) => a - b);
 
    let cost = 0;
 
    // Loop to merge the elements until there are
    // greater than K elements in the array
    while (List.length > k) {
      let Sum = 0;
 
      // Obtain the sum of K minimum elements
      for (let i = 0; i < k; i++) {
        Sum += List[i];
      }
 
      // Remove the K minimum elements from the array
      for (let i = 0; i < k; i++) {
        List.shift();
      }
 
      // Insert the merged element into the sorted array
      // at its correct position
      this.insertInSortedList(List, Sum, 0, List.length);
      cost += Sum;
    }
 
    // If there are only K elements left,
    // take the sum and return the sum, else return -1
    if (List.length === k) {
      cost += List.reduce((a, b) => a + b);
      return cost;
    } else {
      return -1;
    }
  }
}
 
// Driver code
let stones = [];
stones.push(3);
stones.push(2);
stones.push(4);
stones.push(1);
console.log(new GFG().mergeStones(stones, 3));
console.log(new GFG().mergeStones(stones, 2));
 
// This code is contributed by akashish__


Output: 

-1
10

 



Last Updated : 15 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads