Find K items with the lowest values
Last Updated :
23 Apr, 2023
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++
#include <bits/stdc++.h>
using namespace std;
bool comp(pair<string, int > A, pair<string, int > B)
{
if (A.second == B.second)
return A.first < B.first;
return A.second < B.second;
}
int main()
{
int k = 2;
int n = 3;
vector<pair<string, int > > items;
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.begin(), items.end(), comp);
for ( int i = 0; i < min(n, k); ++i) {
cout << items[i].first << '\n' ;
}
return 0;
}
|
Java
import java.util.*;
public class Main {
static boolean comp(Pair A, Pair B)
{
if (A.value == B.value)
return A.key.compareTo(B.key) < 0 ;
return A.value < B.value;
}
public static void main(String[] args) {
int k = 2 ;
int n = 3 ;
List<Pair> items = new ArrayList<>();
items.add( new Pair( "Bat" , 100 ));
items.add( new Pair( "Gloves" , 50 ));
items.add( new Pair( "Wickets" , 200 ));
items.add( new Pair( "Ball" , 100 ));
Collections.sort(items, new Comparator<Pair>() {
public int compare(Pair A, Pair B) {
return comp(A, B) ? - 1 : 1 ;
}
});
for ( int i = 0 ; i < Math.min(n, k); ++i) {
System.out.println(items.get(i).key);
}
}
}
class Pair {
public String key;
public int value;
Pair(String key, int value)
{
this .key = key;
this .value = value;
}
}
|
Python3
from typing import List , Tuple
def comp(A: Tuple [ str , int ], B: Tuple [ str , int ]):
if A[ 1 ] = = B[ 1 ]:
return A[ 0 ] < B[ 0 ]
return A[ 1 ] < B[ 1 ]
k = 2
n = 3
items = [( "Bat" , 100 ),
( "Gloves" , 50 ),
( "Wickets" , 200 ),
( "Ball" , 100 )]
items.sort(key = lambda x: (x[ 1 ], x[ 0 ]))
for i in range ( min (n, k)):
print (items[i][ 0 ])
|
C#
using System;
using System.Collections.Generic;
class Program
{
class Comp : IComparer<KeyValuePair< string , int >>
{
public int Compare(KeyValuePair< string , int > A, KeyValuePair< string , int > B)
{
if (A.Value == B.Value)
return A.Key.CompareTo(B.Key);
return A.Value.CompareTo(B.Value);
}
}
static void Main( string [] args)
{
int k = 2;
int n = 3;
List<KeyValuePair< string , int >> items = new List<KeyValuePair< string , int >>();
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));
items.Sort( new Comp());
for ( int i = 0; i < Math.Min(n, k); ++i)
{
Console.WriteLine(items[i].Key);
}
}
}
|
Javascript
class Pair {
constructor(key, value) {
this .key = key;
this .value = value;
}
}
function comp(A, B) {
if (A.value == B.value) {
return A.key.localeCompare(B.key) < 0;
}
return A.value < B.value;
}
function main() {
const k = 2;
const n = 3;
const items = [];
items.push( new Pair( "Bat" , 100));
items.push( new Pair( "Gloves" , 50));
items.push( new Pair( "Wickets" , 200));
items.push( new Pair( "Ball" , 100));
items.sort((A, B) => (comp(A, B) ? -1 : 1));
for (let i = 0; i < Math.min(n, k); ++i) {
console.log(items[i].key);
}
}
main();
|
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
C++
#include<bits/stdc++.h>
using namespace std;
int main()
{
int k = 2;
int n = 3;
map<string, int > items;
items[ "Bat" ] = 100;
items[ "Gloves" ] = 50;
items[ "Wickets" ] = 200;
items[ "Ball" ] = 100;
priority_queue<pair<string, int >, vector<pair<string, int >>, greater<pair<string, int >>> minHeap;
for ( auto entry : items) {
if (minHeap.size() < k) {
minHeap.push(entry);
}
else {
auto root = minHeap.top();
if (entry.second < root.second) {
minHeap.pop();
minHeap.push(entry);
}
}
}
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 ;
Map<String, Integer> items = new HashMap<>();
items.put( "Bat" , 100 );
items.put( "Gloves" , 50 );
items.put( "Wickets" , 200 );
items.put( "Ball" , 100 );
PriorityQueue<Map.Entry<String, Integer> > minHeap
= new PriorityQueue<>(
Comparator.comparing(Map.Entry::getValue));
for (Map.Entry<String, Integer> entry :
items.entrySet()) {
if (minHeap.size() < k) {
minHeap.add(entry);
}
else {
Map.Entry<String, Integer> root
= minHeap.peek();
if (entry.getValue() < root.getValue()) {
minHeap.poll();
minHeap.add(entry);
}
}
}
for (Map.Entry<String, Integer> entry : minHeap) {
System.out.println(entry.getKey());
}
}
}
|
Python3
def compareEntries(a, b):
return a[ 1 ] - b[ 1 ]
k = 2
n = 3
items = {
"Bat" : 100 ,
"Gloves" : 50 ,
"Wickets" : 200 ,
"Ball" : 100
}
item_tuples = sorted (items.items(), key = lambda x: x[ 1 ])
min_heap = item_tuples[:k]
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 ])
for item in min_heap:
print (item[ 0 ])
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
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;
Dictionary< string , int > items
= new Dictionary< string , int >() {
{ "Bat" , 100 }, { "Gloves" , 50 },
{ "Wickets" , 200 },
{
"Ball" , 100
}
};
List<KeyValuePair< string , int > > itemTuples
= items.ToList();
itemTuples.Sort(CompareEntries);
List<KeyValuePair< string , int > > minHeap
= itemTuples.GetRange(0, k);
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);
}
}
foreach (KeyValuePair< string , int > item in minHeap)
{
Console.WriteLine(item.Key);
}
}
}
|
Javascript
function compareEntries(a, b) {
return a[1] - b[1];
}
let k = 2;
let n = 3;
let items = new Map();
items.set( "Bat" , 100);
items.set( "Gloves" , 50);
items.set( "Wickets" , 200);
items.set( "Ball" , 100);
let minHeap = [];
for (let entry of items) {
if (minHeap.length < k) {
minHeap.push(entry);
minHeap.sort(compareEntries);
} else {
let root = minHeap[0];
if (entry[1] < root[1]) {
minHeap.shift();
minHeap.push(entry);
minHeap.sort(compareEntries);
}
}
}
for (let entry of minHeap) {
console.log(entry[0]);
}
|
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).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...