The problem statement
Given an array of integers nums, return the number of good pairs.
A pair (i, j) is called good if nums[i] == nums[j] and i < j.
Understanding the problem
When reading the above statement our instinct is to do something like this:
- Loop through nums with i as index
- Nest loop through nums with j as index
- if i < j and nums[i] === nums[j]
- increment a counter
- if i < j and nums[i] === nums[j]
- Nest loop through nums with j as index
- return total.
This works. But it leaves us with a time complexity of O(n^2) which is exponential and not ideal.
In order for us to understand the better way around this we need to really read into what the question is asking us to do.
- When we iterate the array, store somewhere the number being iterated and the number of times we have seen that number.
- As we do that, increment a counter which represents the total number of pairs found.
Lets dive into the code and let the code explain itself
Code
function numIdenticalPairs(nums: number[]): number {
// initialise good pairs counter
let goodPairs = 0;
// initialise a map to keep track of previous occurences of numbers
const matches = new Map<number, number>();
for (let i = 0; i < nums.length; i++) {
// if our map has the current number
if (matches.has(nums[i])) {
// increment good pairs by the number of previous occurences of
// the number found in the map. i.e. when we first discover a new number
// we know we have a 1 value of it, so when we see it again goodPairs
// gets incremented by 1.
goodPairs += matches.get(nums[i]);
// then we update the value of the number entry in the map
// to be incremented by one.
matches.set(nums[i], matches.get(nums[i]) + 1);
} else {
matches.set(nums[i], 1);
}
}
return goodPairs;
}
How It Works
Function Definition:
numIdenticalPairsis a function that receives an array of numbers (nums) with the purpose of identifying all identical pairs within the array.Variable Initialization:
goodPairsis a counter initialized at 0, used to tally the number of identical pairs.matchesis a Map that will store each unique number from the array and how many times it appears.
Looping Through the Array:
- The function uses a for loop to iterate over each number in the
numsarray.
- The function uses a for loop to iterate over each number in the
Logic Within the Loop:
- The function checks if the current number is already in the
matchesmap.- If it is, the function increments the
goodPairscounter by the amount stored for that number inmatchesand updates the number's count inmatches. - If not, the function adds the number to
matcheswith a value of 1.
- If it is, the function increments the
- The function checks if the current number is already in the
Conclusion:
- After the loop, the function returns the
goodPairstotal, which is the count of all good (identical) pairs in the array.
- After the loop, the function returns the
In essence, this function systematically checks each number, keeps track of the frequency of each, and accumulates a total count of identical pairs. It does so efficiently, which makes it particularly effective for large arrays of numbers.
Key Takeaways
- Read through a problem and try to think wider than just the default approach. Think outside the box. Truly understand what a simple ask might be after.