Open In App

Find K items with the lowest values

Last Updated : 23 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a list of items and their values. The task is to find k items with the lowest value. It is possible that two items have the same value, in that case item whose name comes first (lexicographically) will be given higher priority. 

Examples:

Input : items[] = {Bat, Gloves, Wickets, Ball}, 
        values[] = {100, 50, 200, 100}
        k = 2
Output : Gloves Ball
Explanation : 
Gloves has the lowest value.
Ball and Bat has the same value but Ball comes first lexicographically.

Approach: 

This question can be solved by picking the items greedily according to the values. We will sort use the items list in the ascending order of the values and in case of the same values items will be sorted lexicographical order increasing order. We will store the data in the form of pairs in a vector and will use an inbuilt sort function with boolean compactor function which will be used to compare two items.

Below is the implementation of the above approach: 

C++




// C++ implementation of above approach
#include <bits/stdc++.h>
using namespace std;
 
// Boolean Comparator Function
// to compare two pairs of item-value
bool comp(pair<string, int> A, pair<string, int> B)
{
    // Compare the name if the values are equal
    if (A.second == B.second)
        return A.first < B.first;
 
    // Else compare values
    return A.second < B.second;
}
 
// Driver code
int main()
{
    int k = 2;
    int n = 3;
 
    // Store data in a vector of Item-Value Pair
    vector<pair<string, int> > items;
 
    // inserting items-value pairs in the vector
    items.push_back(make_pair("Bat", 100));
    items.push_back(make_pair("Gloves", 50));
    items.push_back(make_pair("Wickets", 200));
    items.push_back(make_pair("Ball", 100));
 
    // Sort items using Inbuilt function
    sort(items.begin(), items.end(), comp);
 
    // Print top k values
    // or if n is less than k
    // Print all n items
    for (int i = 0; i < min(n, k); ++i) {
        cout << items[i].first << '\n';
    }
 
    return 0;
}


Java




import java.util.*;
 
public class Main {
 
  // Boolean Comparator Function
  // to compare two pairs of item-value
  static boolean comp(Pair A, Pair B)
  {
    // Compare the name if the values are equal
    if (A.value == B.value)
      return A.key.compareTo(B.key) < 0;
 
    // Else compare values
    return A.value < B.value;
  }
 
  public static void main(String[] args) {
    int k = 2;
    int n = 3;
 
    // Store data in a list of Item-Value Pair
    List<Pair> items = new ArrayList<>();
 
    // inserting items-value pairs in the list
    items.add(new Pair("Bat", 100));
    items.add(new Pair("Gloves", 50));
    items.add(new Pair("Wickets", 200));
    items.add(new Pair("Ball", 100));
 
    // Sort items using Inbuilt function
    Collections.sort(items, new Comparator<Pair>() {
      public int compare(Pair A, Pair B) {
        return comp(A, B) ? -1 : 1;
      }
    });
 
    // Print top k values
    // or if n is less than k
    // Print all n items
    for (int i = 0; i < Math.min(n, k); ++i) {
      System.out.println(items.get(i).key);
    }
  }
}
 
// Declare a pair to store item-value pairs
class Pair {
  public String key;
  public int value;
 
  Pair(String key, int value)
  {
    this.key = key;
    this.value = value;
  }
}
 
// This code is contributed by phsing17.


Python3




from typing import List, Tuple
 
# Boolean Comparator Function
# to compare two pairs of item-value
def comp(A: Tuple[str, int], B: Tuple[str, int]):
    # Compare the name if the values are equal
    if A[1] == B[1]:
        return A[0] < B[0]
    # Else compare values
    return A[1] < B[1]
 
k = 2
n = 3
items = [("Bat", 100),
         ("Gloves", 50),
         ("Wickets", 200),
         ("Ball", 100)]
 
# Sort items using Inbuilt function
items.sort(key=lambda x: (x[1], x[0]))
 
# Print top k values
# or if n is less than k
# Print all n items
for i in range(min(n, k)):
  print(items[i][0])


C#




// C# implementation of above approach
using System;
using System.Collections.Generic;
 
class Program
{
    // Comparator Function
    // to compare two pairs of item-value
    class Comp : IComparer<KeyValuePair<string, int>>
    {
        public int Compare(KeyValuePair<string, int> A, KeyValuePair<string, int> B)
        {
            // Compare the name if the values are equal
            if (A.Value == B.Value)
                return A.Key.CompareTo(B.Key);
 
            // Else compare values
            return A.Value.CompareTo(B.Value);
        }
    }
 
    static void Main(string[] args)
    {
        int k = 2;
        int n = 3;
 
        // Store data in a list of Item-Value Pair
        List<KeyValuePair<string, int>> items = new List<KeyValuePair<string, int>>();
 
        // inserting items-value pairs in the list
        items.Add(new KeyValuePair<string, int>("Bat", 100));
        items.Add(new KeyValuePair<string, int>("Gloves", 50));
        items.Add(new KeyValuePair<string, int>("Wickets", 200));
        items.Add(new KeyValuePair<string, int>("Ball", 100));
 
        // Sort items using Inbuilt function
        items.Sort(new Comp());
 
        // Print top k values
        // or if n is less than k
        // Print all n items
        for (int i = 0; i < Math.Min(n, k); ++i)
        {
            Console.WriteLine(items[i].Key);
        }
    }
}
// Contributed by rishabmalhdijo


Javascript




// Declare a Pair class to store item-value pairs
class Pair {
  constructor(key, value) {
    this.key = key;
    this.value = value;
  }
}
 
// Boolean Comparator Function to compare two pairs of item-value
function comp(A, B) {
  // Compare the name if the values are equal
  if (A.value == B.value) {
    return A.key.localeCompare(B.key) < 0;
  }
  // Else compare values
  return A.value < B.value;
}
 
// Main function
function main() {
  const k = 2;
  const n = 3;
 
  // Store data in a list of Item-Value Pair
  const items = [];
 
  // Inserting items-value pairs in the list
  items.push(new Pair("Bat", 100));
  items.push(new Pair("Gloves", 50));
  items.push(new Pair("Wickets", 200));
  items.push(new Pair("Ball", 100));
 
  // Sort items using Inbuilt function
  items.sort((A, B) => (comp(A, B) ? -1 : 1));
 
  // Print top k values or if n is less than k, print all n items
  for (let i = 0; i < Math.min(n, k); ++i) {
    console.log(items[i].key);
  }
}
 
// Invoke the main function
main();


Output

Gloves
Ball

Time Complexity: O(NlogN) 

Space Complexity: O(1) as no extra space has been taken. Input values storage vector space is neglected.

Further Optimization: We can use heap based method to find k largest elements efficiently.

Approach 2:- 

  1. Using HashMap to store the items and their values. 
  2. Then created a MinHeap using the PriorityQueue class in Java. I have compared the Map. Entry objects based on their values using the Comparator. comparing() method. I have then inserted the first K items in the heap and iterated over the remaining items to find the K items with the lowest values.
  3. To find the K items with the lowest values is to use a MinHeap. 
  4. We can create a MinHeap of size K and insert the first K items in the heap. Then we iterate over the remaining items and compare their values with the root of the heap. 
  5. If the value of the item is less than the root value, we replace the root with the current item and heapify the heap. 
  6. Finally, we will have K items in the heap with the lowest values.

Implementation: MinHeap approach

C++




#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int k = 2;
    int n = 3;
    // Store data in a Map of Item-Value Pair
    map<string, int> items;
    items["Bat"] = 100;
    items["Gloves"] = 50;
    items["Wickets"] = 200;
    items["Ball"] = 100;
 
    // Create a MinHeap of size K
    priority_queue<pair<string, int>, vector<pair<string, int>>, greater<pair<string, int>>> minHeap;
 
    // Insert first K items in the MinHeap
    for (auto entry : items) {
        if (minHeap.size() < k) {
            minHeap.push(entry);
        }
        else {
            // Compare the current item with the root of
            // the heap
            auto root = minHeap.top();
            if (entry.second < root.second) {
                minHeap.pop();
                minHeap.push(entry);
            }
        }
    }
 
    // Print the K items with the lowest values
    while (!minHeap.empty()) {
        auto entry = minHeap.top();
        cout << entry.first << "\n";
        minHeap.pop();
    }
    return 0;
}


Java




import java.util.*;
 
public class Main {
 
    public static void main(String[] args)
    {
        int k = 2;
        int n = 3;
        // Store data in a Map of Item-Value Pair
        Map<String, Integer> items = new HashMap<>();
        items.put("Bat", 100);
        items.put("Gloves", 50);
        items.put("Wickets", 200);
        items.put("Ball", 100);
 
        // Create a MinHeap of size K
        PriorityQueue<Map.Entry<String, Integer> > minHeap
            = new PriorityQueue<>(
                Comparator.comparing(Map.Entry::getValue));
 
        // Insert first K items in the MinHeap
        for (Map.Entry<String, Integer> entry :
             items.entrySet()) {
            if (minHeap.size() < k) {
                minHeap.add(entry);
            }
            else {
                // Compare the current item with the root of
                // the heap
                Map.Entry<String, Integer> root
                    = minHeap.peek();
                if (entry.getValue() < root.getValue()) {
                    minHeap.poll();
                    minHeap.add(entry);
                }
            }
        }
 
        // Print the K items with the lowest values
        for (Map.Entry<String, Integer> entry : minHeap) {
            System.out.println(entry.getKey());
        }
    }
}


Python3




# Function to compare two entries
def compareEntries(a, b):
    return a[1] - b[1]
 
 
# Main function
k = 2
n = 3
 
# Store data in a dictionary of Item-Value Pair
items = {
    "Bat": 100,
    "Gloves": 50,
    "Wickets": 200,
    "Ball": 100
}
 
# Create a list of tuples and sort by value
item_tuples = sorted(items.items(), key=lambda x: x[1])
 
# Get the K items with the lowest values
min_heap = item_tuples[:k]
 
# Insert remaining items into the heap
for i in range(k, len(item_tuples)):
    if item_tuples[i][1] < min_heap[-1][1]:
        min_heap.pop()
        min_heap.append(item_tuples[i])
        min_heap.sort(key=lambda x: x[1])
 
# Print the K items with the lowest values
for item in min_heap:
    print(item[0])


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
    // Function to compare two entries
    static int CompareEntries(KeyValuePair<string, int> a,
                              KeyValuePair<string, int> b)
    {
        return a.Value - b.Value;
    }
 
    static void Main(string[] args)
    {
        int k = 2;
        int n = 3;
 
        // Store data in a dictionary of Item-Value Pair
        Dictionary<string, int> items
            = new Dictionary<string, int>() {
                  { "Bat", 100 }, { "Gloves", 50 },
                      { "Wickets", 200 },
                  {
                      "Ball", 100
                  }
              };
 
        // Create a list of tuples and sort by value
        List<KeyValuePair<string, int> > itemTuples
            = items.ToList();
        itemTuples.Sort(CompareEntries);
 
        // Get the K items with the lowest values
        List<KeyValuePair<string, int> > minHeap
            = itemTuples.GetRange(0, k);
 
        // Insert remaining items into the heap
        for (int i = k; i < itemTuples.Count; i++) {
            if (itemTuples[i].Value
                < minHeap.Last().Value) {
                minHeap.Remove(minHeap.Last());
                minHeap.Add(itemTuples[i]);
                minHeap.Sort(CompareEntries);
            }
        }
 
        // Print the K items with the lowest values
        foreach(KeyValuePair<string, int> item in minHeap)
        {
            Console.WriteLine(item.Key);
        }
    }
}


Javascript




// Function to compare two entries
function compareEntries(a, b) {
    return a[1] - b[1];
}
 
// Main function
let k = 2;
let n = 3;
 
// Store data in a Map of Item-Value Pair
let items = new Map();
items.set("Bat", 100);
items.set("Gloves", 50);
items.set("Wickets", 200);
items.set("Ball", 100);
 
// Create a MinHeap of size K
let minHeap = [];
 
// Insert first K items in the MinHeap
for (let entry of items) {
    if (minHeap.length < k) {
        minHeap.push(entry);
        minHeap.sort(compareEntries);
    } else {
        // Compare the current item with the root of the heap
        let root = minHeap[0];
        if (entry[1] < root[1]) {
            minHeap.shift();
            minHeap.push(entry);
            minHeap.sort(compareEntries);
        }
    }
}
 
// Print the K items with the lowest values
for (let entry of minHeap) {
    console.log(entry[0]);
}


Output

Gloves
Bat

Time Complexity: 

  1. Insertion of N items into the HashMap takes O(N) time.
  2. Insertion and removal operations in the PriorityQueue take O(log K) time.
  3. We perform N-K iterations over the remaining items to find the K items with the lowest values. Each iteration involves the comparison of the current item with the root of the heap, which takes O(log K) time.
  4. Printing the K items with the lowest values takes O(K) time.
  5. Therefore, the overall time complexity of the code is O(N log K).

Auxiliary Space: 

  1. We use a HashMap to store the N items, which requires O(N) space.
  2. We use a MinHeap of size K to find the K items with the lowest values, which requires O(K) space.
  3. We do not use any additional data structure, so the overall auxiliary space complexity of the code is O(N + K).
  4. Therefore, the space complexity of the code is O(N + K).


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

Similar Reads