Given two lists list1 and list2 containing m and n items respectively. Each item is associated with two fields: name and price. The problem is to count items that are in both the lists but with different prices.
Examples:
Input : list1[] = {{"apple", 60}, {"bread", 20},
{"wheat", 50}, {"oil", 30}}
list2[] = {{"milk", 20}, {"bread", 15},
{"wheat", 40}, {"apple", 60}}
Output : 2
bread and wheat are the two items common to both the
lists but with different prices.
Source: Cognizant Interview Experience | Set 5.
Method 1 (Naive Approach): Using two nested loops compare each item of list1 with all the items of list2. If a match is found with a different price then increment the count.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct item
{
string name;
int price;
};
int countItems(item list1[], int m,
item list2[], int n)
{
int count = 0;
for ( int i = 0; i < m; i++)
for ( int j = 0; j < n; j++)
if ((list1[i].name.compare(list2[j].name) == 0) &&
(list1[i].price != list2[j].price))
count++;
return count;
}
int main()
{
item list1[] = {{ "apple" , 60}, { "bread" , 20},
{ "wheat" , 50}, { "oil" , 30}};
item list2[] = {{ "milk" , 20}, { "bread" , 15},
{ "wheat" , 40}, { "apple" , 60}};
int m = sizeof (list1) / sizeof (list1[0]);
int n = sizeof (list2) / sizeof (list2[0]);
cout << "Count = "
<< countItems(list1, m, list2, n);
return 0;
}
|
Java
class GFG{
static class item
{
String name;
int price;
public item(String name, int price) {
this .name = name;
this .price = price;
}
};
static int countItems(item list1[], int m,
item list2[], int n)
{
int count = 0 ;
for ( int i = 0 ; i < m; i++)
for ( int j = 0 ; j < n; j++)
if ((list1[i].name.compareTo(list2[j].name) == 0 ) &&
(list1[i].price != list2[j].price))
count++;
return count;
}
public static void main(String[] args)
{
item list1[] = { new item( "apple" , 60 ), new item( "bread" , 20 ),
new item( "wheat" , 50 ), new item( "oil" , 30 )};
item list2[] = { new item( "milk" , 20 ), new item( "bread" , 15 ),
new item( "wheat" , 40 ), new item( "apple" , 60 )};
int m = list1.length;
int n = list2.length;
System.out.print( "Count = "
+ countItems(list1, m, list2, n));
}
}
|
Python3
def countItems(list1, list2):
count = 0
for i in list1:
for j in list2:
if i[ 0 ] = = j[ 0 ] and i[ 1 ] ! = j[ 1 ]:
count + = 1
return count
list1 = [( "apple" , 60 ), ( "bread" , 20 ),
( "wheat" , 50 ), ( "oil" , 30 )]
list2 = [( "milk" , 20 ), ( "bread" , 15 ),
( "wheat" , 40 ), ( "apple" , 60 )]
print ( "Count = " , countItems(list1, list2))
|
C#
using System;
class GFG{
class item
{
public String name;
public int price;
public item(String name, int price) {
this .name = name;
this .price = price;
}
};
static int countItems(item []list1, int m,
item []list2, int n)
{
int count = 0;
for ( int i = 0; i < m; i++)
for ( int j = 0; j < n; j++)
if ((list1[i].name.CompareTo(list2[j].name) == 0) &&
(list1[i].price != list2[j].price))
count++;
return count;
}
public static void Main(String[] args)
{
item []list1 = { new item( "apple" , 60), new item( "bread" , 20),
new item( "wheat" , 50), new item( "oil" , 30)};
item []list2 = { new item( "milk" , 20), new item( "bread" , 15),
new item( "wheat" , 40), new item( "apple" , 60)};
int m = list1.Length;
int n = list2.Length;
Console.Write( "Count = "
+ countItems(list1, m, list2, n));
}
}
|
Javascript
<script>
function countItems(list1, m, list2, n)
{
var count = 0;
for ( var i = 0; i < m; i++)
for ( var j = 0; j < n; j++)
if (list1[i][0] === list2[j][0] &&
(list1[i][1] != list2[j][1]))
count++;
return count;
}
var list1 = [[ "apple" , 60], [ "bread" , 20],
[ "wheat" , 50], [ "oil" , 30]];
var list2 = [[ "milk" , 20], [ "bread" , 15],
[ "wheat" , 40], [ "apple" , 60]];
var m = list1.length;
var n = list2.length;
document.write( "Count = " + countItems(list1, m, list2, n));
</script>
|
Time Complexity: O(m*n).
Auxiliary Space: O(1).
Method 2 (Binary Search): Sort the list2 in alphabetical order of its items name. Now, for each item of list1 check whether it in present in list2 using the binary search technique and get its price from list2. If prices are different then increment the count.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct item
{
string name;
int price;
};
bool compare( struct item a,
struct item b)
{
return (a.name.compare
(b.name) <= 0);
}
int binary_search(item list2[], int low,
int high, string str)
{
while (low <= high)
{
int mid = (low + high) / 2;
if (list2[mid].name.compare(str) == 0)
return list2[mid].price;
else if (list2[mid].name.compare(str) < 0)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int countItems(item list1[], int m,
item list2[], int n)
{
sort(list2, list2 + n,
compare);
int count = 0;
for ( int i = 0; i < m; i++)
{
int r = binary_search(list2, 0, n - 1,
list1[i].name);
if ((r != -1) &&
(r != list1[i].price))
count++;
}
return count;
}
int main()
{
item list1[] = {{ "apple" , 60},
{ "bread" , 20},
{ "wheat" , 50},
{ "oil" , 30}};
item list2[] = {{ "milk" , 20},
{ "bread" , 15},
{ "wheat" , 40},
{ "apple" , 60}};
int m = sizeof (list1) /
sizeof (list1[0]);
int n = sizeof (list2) /
sizeof (list2[0]);
cout << "Count = " <<
countItems(list1, m,
list2, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class item
{
String name;
int price;
item(String name,
int price)
{
this .name = name;
this .price = price;
}
};
static class Com implements Comparator<item>
{
public int compare(item a,
item b)
{
return a.name.compareTo(b.name);
}
}
static int binary_search(item list2[],
int low, int high,
String str)
{
while (low <= high)
{
int mid = (low + high) / 2 ;
if (list2[mid].name.compareTo(str) == 0 )
return list2[mid].price;
else if (list2[mid].name.compareTo(str) < 0 )
low = mid + 1 ;
else
high = mid - 1 ;
}
return - 1 ;
}
static int countItems(item list1[], int m,
item list2[], int n)
{
Arrays.sort(list2, new Com());
int count = 0 ;
for ( int i = 0 ; i < m; i++)
{
int r = binary_search(list2, 0 ,
n - 1 ,
list1[i].name);
if ((r != - 1 ) &&
(r != list1[i].price))
count++;
}
return count;
}
public static void main(String[] args)
{
item[] list1 = { new item( "apple" , 60 ),
new item( "bread" , 20 ),
new item( "wheat" , 50 ),
new item( "oil" , 30 )};
item list2[] = { new item( "milk" , 20 ),
new item( "bread" , 15 ),
new item( "wheat" , 40 ),
new item( "apple" , 60 )};
int m = list1.length;
int n = list2.length;
System.out.print( "Count = " +
countItems(list1, m,
list2, n));
}
}
|
Python3
from ast import Str
from functools import cmp_to_key
class item:
def __init__( self , name, price):
self .name = name
self .price = price
def binary_search(list2, low, high, str ):
while (low < = high):
mid = ((low + high) / / 2 )
if (list2[mid].name = = str ):
return list2[mid].price
elif (list2[mid].name < str ):
low = mid + 1
else :
high = mid - 1
return - 1
def custom_logic(a, b):
return a.name = = b.name
def countItems(list1, m, list2, n):
sorted (list2,key = cmp_to_key(custom_logic))
count = 0
for i in range (m):
r = binary_search(list2, 0 ,
n - 1 ,
list1[i].name)
if ((r ! = - 1 ) and (r ! = list1[i].price)):
count + = 1
return count
list1 = [item( "apple" , 60 ),
item( "bread" , 20 ),
item( "wheat" , 50 ),
item( "oil" , 30 )]
list2 = [item( "milk" , 20 ),
item( "bread" , 15 ),
item( "wheat" , 40 ),
item( "apple" , 60 )]
m = len (list1)
n = len (list2)
print (f "Count = {countItems(list1, m,list2, n)}" )
|
Javascript
<script>
class item
{
constructor(name,price)
{
this .name = name;
this .price = price;
}
}
function binary_search(list2,low,high,str)
{
while (low <= high)
{
let mid = Math.floor((low + high) / 2);
if (list2[mid].name == (str))
return list2[mid].price;
else if (list2[mid].name < (str))
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
function countItems(list1, m, list2, n)
{
list2.sort( function (a,b){ return a.name==b.name;});
let count = 0;
for (let i = 0; i < m; i++)
{
let r = binary_search(list2, 0,
n - 1,
list1[i].name);
if ((r != -1) &&
(r != list1[i].price))
count++;
}
return count;
}
let list1=[ new item( "apple" , 60),
new item( "bread" , 20),
new item( "wheat" , 50),
new item( "oil" , 30)];
let list2=[ new item( "milk" , 20),
new item( "bread" , 15),
new item( "wheat" , 40),
new item( "apple" , 60)];
let m = list1.length;
let n = list2.length;
document.write( "Count = " +
countItems(list1, m,
list2, n));
</script>
|
C#
using System;
class Item
{
public string name;
public int price;
public Item( string name, int price)
{
this .name = name;
this .price = price;
}
}
class Program
{
static int BinarySearch(Item[] list2, int low, int high, string str)
{
while (low <= high)
{
int mid = (low + high) / 2;
if (list2[mid].name == str)
{
return list2[mid].price;
}
else if (list2[mid].name.CompareTo(str) < 0)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
return -1;
}
static int CountItems(Item[] list1, int m, Item[] list2, int n)
{
Array.Sort(list2, (a, b) => a.name.CompareTo(b.name));
int count = 0;
for ( int i = 0; i < m; i++)
{
int r = BinarySearch(list2, 0, n - 1, list1[i].name);
if ((r != -1) && (r != list1[i].price))
{
count++;
}
}
return count;
}
static void Main( string [] args)
{
Item[] list1 = new Item[] {
new Item( "apple" , 60),
new Item( "bread" , 20),
new Item( "wheat" , 50),
new Item( "oil" , 30)
};
Item[] list2 = new Item[] {
new Item( "milk" , 20),
new Item( "bread" , 15),
new Item( "wheat" , 40),
new Item( "apple" , 60)
};
int m = list1.Length;
int n = list2.Length;
Console.WriteLine( "Count = " + CountItems(list1, m, list2, n));
}
}
|
Time Complexity: (m*log2n).
Auxiliary Space: O(1).
For efficiency, the list with the maximum number of elements should be sorted and used for binary search.
Method 3 (Efficient Approach): Create a hash table with (key, value) tuple as (item name, price). Insert the elements of list1 in the hash table. Now, for each element of list2 check if it is the hash table or not. If it is present, then check if its price is different from the value from the hash table. If so then increment the count.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct item
{
string name;
int price;
};
int countItems(item list1[], int m,
item list2[], int n)
{
unordered_map<string, int > um;
int count = 0;
for ( int i = 0; i < m; i++)
um[list1[i].name] = list1[i].price;
for ( int i = 0; i < n; i++)
if ((um.find(list2[i].name) != um.end()) &&
(um[list2[i].name] != list2[i].price))
count++;
return count;
}
int main()
{
item list1[] = {{ "apple" , 60}, { "bread" , 20},
{ "wheat" , 50}, { "oil" , 30}};
item list2[] = {{ "milk" , 20}, { "bread" , 15},
{ "wheat" , 40}, { "apple" , 60}};
int m = sizeof (list1) / sizeof (list1[0]);
int n = sizeof (list2) / sizeof (list2[0]);
cout << "Count = "
<< countItems(list1, m, list2, n);
return 0;
}
|
Java
import java.util.*;
class GFG {
static class item {
String name;
int price;
public item(String name, int price)
{
this .name = name;
this .price = price;
}
};
static int countItems(item list1[], int m, item list2[],
int n)
{
HashMap<String, Integer> um = new HashMap<>();
int count = 0 ;
for ( int i = 0 ; i < m; i++)
um.put(list1[i].name, list1[i].price);
for ( int i = 0 ; i < n; i++)
if ((um.containsKey(list2[i].name))
&& (um.get(list2[i].name)
!= list2[i].price))
count++;
return count;
}
public static void main(String[] args)
{
item list1[] = { new item( "apple" , 60 ),
new item( "bread" , 20 ),
new item( "wheat" , 50 ),
new item( "oil" , 30 ) };
item list2[]
= { new item( "milk" , 20 ), new item( "bread" , 15 ),
new item( "wheat" , 40 ),
new item( "apple" , 60 ) };
int m = list1.length;
int n = list2.length;
System.out.print( "Count = "
+ countItems(list1, m, list2, n));
}
}
|
Python3
class item:
def __init__( self , name, price):
self .name = name
self .price = price
def countItems(list1, m,list2, n):
um = {}
count = 0
for i in range (m):
um[list1[i].name] = list1[i].price;
for i in range (n):
if ((um.get(list2[i].name) ! = None ) and (um[list2[i].name] ! = list2[i].price)):
count + = 1
return count
list1 = [item( "apple" , 60 ),
item( "bread" , 20 ),
item( "wheat" , 50 ),
item( "oil" , 30 )]
list2 = [item( "milk" , 20 ),
item( "bread" , 15 ),
item( "wheat" , 40 ),
item( "apple" , 60 )]
m = len (list1)
n = len (list2)
print ( "Count = " ,countItems(list1, m, list2, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
public class item
{
public String name;
public int price;
public item(String name,
int price)
{
this .name = name;
this .price = price;
}
};
static int countItems(item []list1, int m,
item []list2, int n)
{
Dictionary<String,
int > um = new Dictionary<String,
int >();
int count = 0;
for ( int i = 0; i < m; i++)
um.Add(list1[i].name,
list1[i].price);
for ( int i = 0; i < n; i++)
if ((um.ContainsKey(list2[i].name)) &&
(um[list2[i].name] != list2[i].price))
count++;
return count;
}
public static void Main(String[] args)
{
item []list1 = { new item( "apple" , 60),
new item( "bread" , 20),
new item( "wheat" , 50),
new item( "oil" , 30)};
item []list2 = { new item( "milk" , 20),
new item( "bread" , 15),
new item( "wheat" , 40),
new item( "apple" , 60)};
int m = list1.Length;
int n = list2.Length;
Console.Write( "Count = " +
countItems(list1, m,
list2, n));
}
}
|
Javascript
<script>
class item
{
constructor(name,price)
{
this .name = name;
this .price = price;
}
}
function countItems(list1,m,list2,n)
{
let um = new Map();
let count = 0;
for (let i = 0; i < m; i++)
um.set(list1[i].name, list1[i].price);
for (let i = 0; i < n; i++)
if ((um.has(list2[i].name)) &&
(um.get(list2[i].name) != list2[i].price))
count++;
return count;
}
let list1=[ new item( "apple" , 60),
new item( "bread" , 20),
new item( "wheat" , 50),
new item( "oil" , 30)];
let list2=[ new item( "milk" , 20),
new item( "bread" , 15),
new item( "wheat" , 40),
new item( "apple" , 60)];
let m = list1.length;
let n = list2.length;
document.write( "Count = " +
countItems(list1, m,
list2, n));
</script>
|
Time Complexity: O(m + n).
Auxiliary Space: O(m).
For efficiency, the list having a minimum number of elements should be inserted in the hash table.