Minimum number of stacks possible using boxes of given capacities

Given N boxes with their capacities which denotes the total number of boxes that it can hold above it. You can stack up the boxes one over the other as long as the total number of boxes above each box is less than or equal to its capacity. Find the minimum number of stacks that can be made by using all the boxes.
Examples:Â
Input: arr[] = {0, 0, 1, 1, 2}Â
Output: 2Â
First stack (top to bottom): 0 1 2Â
Second stack (top to bottom): 0 1Input: arr[] = {1, 1, 4, 4}Â
Output: 1Â
All the boxes can be put on a single stack.Â
Â
Approach: Let’s have a map in which map[X] denotes the number of boxes with capacity X available with us. Let’s build stacks one by one. Initially the size of the stack would be 0, and then we iterate through the map greedily choosing as many boxes of current capacity as we can.
Below is the implementation of the above approach:Â Â
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;Â
// Function to return the count// of minimum stacksint countPiles(int n, int a[]){Â
    // Keep track of occurrence    // of each capacity    map<int, int> occ;Â
    // Fill the occurrence map    for (int i = 0; i < n; i++)        occ[a[i]]++;Â
    // Number of piles is 0 initially    int pile = 0;Â
    // Traverse occurrences in increasing    // order of capacities.    while (occ.size()) {Â
        // Adding a new pile        pile++;        int size = 0;        unordered_set<int> toRemove;Â
        // Traverse all piles in increasing        // order of capacities        for (auto tm : occ) {            int mx = tm.first;            int ct = tm.second;Â
            // Number of boxes of capacity mx            // that can be added to current pile            int use = min(ct, mx - size + 1);Â
            // Update the occurrence            occ[mx] -= use;Â
            // Update the size of the pile            size += use;            if (occ[mx] == 0)                toRemove.insert(mx);        }Â
        // Remove capacities that are        // no longer available        for (auto tm : toRemove)            occ.erase(tm);    }    return pile;}Â
// Driver codeint main(){Â Â Â Â int a[] = { 0, 0, 1, 1, 2 };Â Â Â Â int n = sizeof(a) / sizeof(a[0]);Â Â Â Â cout << countPiles(n, a);Â
    return 0;} |
Java
// Java implementation of the approachimport java.util.HashMap;import java.util.HashSet;Â
class GFG {Â
    // Function to return the count    // of minimum stacks    static int countPiles(int n, int[] a)     {Â
        // Keep track of occurrence        // of each capacity        HashMap<Integer,                 Integer> occ = new HashMap<>();Â
        // Fill the occurrence map        for (int i = 0; i < n; i++)            occ.put(a[i], occ.get(a[i]) == null ? 1 :                           occ.get(a[i]) + 1);Â
        // Number of piles is 0 initially        int pile = 0;Â
        // Traverse occurrences in increasing        // order of capacities.        while (!occ.isEmpty())         {Â
            // Adding a new pile            pile++;            int size = 0;            HashSet<Integer> toRemove = new HashSet<>();Â
            // Traverse all piles in increasing            // order of capacities            for (HashMap.Entry<Integer,                               Integer> tm : occ.entrySet())            {                int mx = tm.getKey();                int ct = tm.getValue();Â
                // Number of boxes of capacity mx                // that can be added to current pile                int use = Math.min(ct, mx - size + 1);Â
                // Update the occurrence                occ.put(mx, occ.get(mx) - use);Â
                // Update the size of the pile                size += use;                if (occ.get(mx) == 0)                    toRemove.add(mx);            }Â
            // Remove capacities that are            // no longer available            for (int tm : toRemove)                occ.remove(tm);        }        return pile;    }Â
    // Driver Code    public static void main(String[] args)     {        int[] a = { 0, 0, 1, 1, 2 };        int n = a.length;Â
        System.out.println(countPiles(n, a));    }}Â
// This code is contributed by// sanjeev2552 |
Python3
# Python3 implementation of the approachÂ
# Function to return the count# of minimum stacksdef countPiles(n, a):         # Keep track of occurrence    # of each capacity    occ = dict()Â
    # Fill the occurrence map    for i in a:        if i in occ.keys():            occ[i] += 1        else:            occ[i] = 1Â
    # Number of piles is 0 initially    pile = 0Â
    # Traverse occurrences in increasing    # order of capacities.    while (len(occ) > 0):Â
        # Adding a new pile        pile += 1        size = 0        toRemove = dict()Â
        # Traverse all piles in increasing        # order of capacities        for tm in occ:            mx = tm            ct = occ[tm]Â
            # Number of boxes of capacity mx            # that can be added to current pile            use = min(ct, mx - size + 1)Â
            # Update the occurrence            occ[mx] -= useÂ
            # Update the size of the pile            size += use            if (occ[mx] == 0):                toRemove[mx] = 1                 # Remove capacities that are        # no longer available        for tm in toRemove:            del occ[tm]         return pileÂ
# Driver codea = [0, 0, 1, 1, 2]n = len(a)print(countPiles(n, a))Â
# This code is contributed # by Mohit Kumar |
C#
// C# implementation of the approachusing System;using System.Collections;using System.Collections.Generic;using System.Linq;Â
class GFG {Â
  // Function to return the count  // of minimum stacks  static int countPiles(int n, int[] a)   {Â
    // Keep track of occurrence    // of each capacity    Dictionary<int,     int> occ = new Dictionary<int,int>();Â
    // Fill the occurrence map    for (int i = 0; i < n; i++)    {      if(!occ.ContainsKey(a[i]))      {        occ[a[i]]=0;      }Â
      occ[a[i]]++;    }Â
    // Number of piles is 0 initially    int pile = 0;Â
    // Traverse occurrences in increasing    // order of capacities.    while(occ.Count!=0)     {Â
      // Adding a new pile      pile++;      int size = 0;      HashSet<int> toRemove = new HashSet<int>();Â
      Dictionary<int,int> tmp = occ;Â
      // Traverse all piles in increasing      // order of capacities      foreach(var tm in occ.Keys.ToList())      {        int mx = tm;        int ct = occ[tm];Â
        // Number of boxes of capacity mx        // that can be added to current pile        int use = Math.Min(ct, mx - size + 1);Â
        // Update the occurrence        occ[mx]-= use;Â
        // Update the size of the pile        size += use;Â
        if (occ[mx] == 0)          toRemove.Add(mx);      }Â
      occ = tmp;             // Remove capacities that are      // no longer available      foreach(int tm in toRemove.ToList())        occ.Remove(tm);    }    return pile;  }Â
  // Driver Code  public static void Main(string[] args)   {    int[] a = { 0, 0, 1, 1, 2 };    int n = a.Length;Â
    Console.WriteLine(countPiles(n, a));  }}Â
// This code is contributed by rutvik_56. |
Javascript
<script>Â
// Javascript implementation of the approachÂ
// Function to return the count// of minimum stacksfunction countPiles(n, a){         // Keep track of occurrence    // of each capacity    let occ = new Map();Â
    // Fill the occurrence map    for(let i = 0; i < n; i++)        occ.set(a[i], occ.get(a[i]) == null ? 1 :                      occ.get(a[i]) + 1);Â
    // Number of piles is 0 initially    let pile = 0;Â
    // Traverse occurrences in increasing    // order of capacities.    while (occ.size != 0)    {Â
        // Adding a new pile        pile++;        let size = 0;        let toRemove = new Set();Â
        // Traverse all piles in increasing        // order of capacities        for(let [key, value] of occ.entries())        {            let mx = key;            let ct = value;Â
            // Number of boxes of capacity mx            // that can be added to current pile            let use = Math.min(ct, mx - size + 1);Â
            // Update the occurrence            occ.set(mx, occ.get(mx) - use);Â
            // Update the size of the pile            size += use;                         if (occ.get(mx) == 0)                toRemove.add(mx);        }Â
        // Remove capacities that are        // no longer available        for(let tm of toRemove.values())            occ.delete(tm);    }    return pile;}Â
// Driver Codelet a = [ 0, 0, 1, 1, 2 ];let n = a.length;Â
document.write(countPiles(n, a));Â
// This code is contributed by unknown2108Â
</script> |
2
Â
Time Complexity: O(NlogN)
 Auxiliary Space: O(N), where N is the size of the given input array.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



