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++ 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;
} |
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. |
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# 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 |
// 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(); |
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:-
- Using HashMap to store the items and their values.
- 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.
- To find the K items with the lowest values is to use a MinHeap.
- 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.
- If the value of the item is less than the root value, we replace the root with the current item and heapify the heap.
- Finally, we will have K items in the heap with the lowest values.
Implementation: MinHeap approach
#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;
} |
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());
}
}
} |
# 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 ])
|
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);
}
}
} |
// 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]);
} |
Gloves Bat
Time Complexity:
- Insertion of N items into the HashMap takes O(N) time.
- Insertion and removal operations in the PriorityQueue take O(log K) time.
- 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.
- Printing the K items with the lowest values takes O(K) time.
- Therefore, the overall time complexity of the code is O(N log K).
Auxiliary Space:
- We use a HashMap to store the N items, which requires O(N) space.
- We use a MinHeap of size K to find the K items with the lowest values, which requires O(K) space.
- We do not use any additional data structure, so the overall auxiliary space complexity of the code is O(N + K).
- Therefore, the space complexity of the code is O(N + K).