John works at a clothing store. He has a large pile of socks that he must pair by color for sale. Given an array of integers representing the color of each sock, determine how many pairs of socks with matching colors there are.
For example, there are n = 7 socks with colors ar = [1, 2, 1, 2, 1, 3, 2]. There is one pair of color 1 and one of color 2. There are three odd socks left, one of each color. The number of pairs is 2.
Given the number of socks in the pile n and an array of colors of each sock, how many pairs do we have?
First solution:
static int sockMerchant(int n, int[] ar) {
int pairs = 0;
HashSet<int> set = new HashSet<int>();
foreach (int i in ar)
{
if (set.Contains(i)) continue;
int[] matchedItems = Array.FindAll(ar, x => i == x);
int occurrencies = matchedItems.Length;
if (occurrencies > 1)
pairs += ((occurrencies - (occurrencies % 2)) / 2);
set.Add(i);
}
return pairs;
}
Second solution:
After showing the first solution to Serhii Dyshko at this post on LinkedIn I optimized the first solution using LINQ and came up with this another solution:
static int sockMerchant(int[] ar)
{
int pairs = 0;
int[] colorsCount = ar.GroupBy(color => color).
Select(color => color.Count()).
ToArray();
foreach (int count in colorsCount)
{
pairs += ((count - (count % 2)) / 2);
}
return pairs;
}
Third solution:
As you can see, both solutions has a complexity of O(N^2) and this is not a good for performance. So, I have reasearched a little more on the web and asked for help on some Slack groups and received the solution bellow, proposed by Higor Ramos with a complexity of O(N):
static int SockMerchant(int[] ar)
{
var socksPairs = new Dictionary<int, int>();
int nSocks = 0;
for (var i = 0; i < ar.Length; i++) {
var current = ar[i];
if (socksPairs.ContainsKey(current)) {
socksPairs[current]++;
if (socksPairs[current] == 2) {
nSocks++;
socksPairs[current] = 0;
}
} else {
socksPairs[current] = 1;
}
}
return nSocks;
}
This Sock Merchant challenge is part of HackerRank
Top comments (0)