2190. Most Frequent Number Following Key In an Array
Problem Description
The problem presents us with an array of integers named nums
and an integer key
, which is guaranteed to be found within nums
. Our objective is to identify the integer in nums
that follows key
the most frequently. To clarify, we are looking for the value target
that appears exactly one position after key
(i.e., nums[i + 1] == target
when nums[i] == key
) the greatest number of times throughout the array.
We should iterate through the array, checking pairs of consecutive numbers (nums[i]
and nums[i + 1]
). We need to keep track of how many times each target
comes after key
, and then return the target
number that has the highest frequency of appearing immediately after key
. If multiple target
numbers have the same frequency, we only return the one with the maximum count, which per the problem description, is unique.
Intuition
To solve the problem, one efficient approach is to traverse through nums
and use a data structure to keep a tally of the frequencies of each target
that follows key
. A common data structure that can be used for this purpose is a Counter (available in Python's collections
module), which will hold target
integers as keys and their counts as values.
We start by initializing an empty Counter object. As we loop through the array, we examine each pair of adjacent elements (nums[i]
and nums[i + 1]
). When we find an occurrence of key
, we increment the count for the following number (nums[i + 1]
). While doing this, we keep track of both the number with the maximum count encountered so far, and the current maximum count. If at any point we find a target
with a higher count than the previous maximum, we update both the ans
(answer) with the new target
and mx
(maximum count) with the new count.
Finally, once we've passed through the array, the variable ans
will hold the target
with the highest frequency of occurrence immediately following key
, and that is what we return.
Solution Approach
The implementation of the solution uses a Counter
from Python's collections
module to track the frequency of each integer appearing immediately after the key
. Also, it leverages the pairwise
iterator from Python's itertools
module to efficiently iterate over the array in adjacent pairs. Here is a step-by-step explanation of the code:
-
Initialize a
Counter
object namedcnt
to hold the frequencies, and two variablesans
andmx
to keep track of the answer (the most frequented target number) and the maximum frequency encountered so far, respectively. -
Use
pairwise(nums)
to create an iterator that returns consecutive pairs of elements innums
. This will look like(nums[0], nums[1]), (nums[1], nums[2]), ..., (nums[n-2], nums[n-1])
. -
Iterate over these pairs of numbers
a
(current key) andb
(potential target):-
If
a
(the current number) is equal tokey
, it meansb
is immediately followingkey
. Then increment the counter forb
by 1:cnt[b] += 1
. -
After incrementing, check if the count for
b
exceeds the current maximum (mx
). If it does, updatemx
to the new count forb
, and setans
tob
becauseb
is now the new target with the maximum count followingkey
.
-
-
Once the loop concludes,
ans
will hold the value of the most frequent target afterkey
, and we returnans
as the solution.
The use of a Counter
object is crucial in this approach for efficient frequency tracking, which allows for the update and query operations to happen in constant time (O(1)). The pairwise
utility simplifies the process of inspecting adjacent elements without having to manage index values manually. Together, these strategies offer a straightforward and efficient solution for the given problem description.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's illustrate the solution approach with a small example:
nums = [1, 2, 3, 2, 2, 3, 4, 2, 5] key = 2
Here, our task is to find the number that most frequently appears immediately after the key
, which in this case is the integer 2
.
-
We initialize the
Counter
objectcnt
as empty,ans
asNone
, andmx
(maximum frequency) as0
. -
We create
pairwise
pairs fromnums
, which would look like this:(1, 2), (2, 3), (3, 2), (2, 2), (2, 3), (3, 4), (4, 2), (2, 5)
Notice that the number
2
, our key, appears in the first slot of several pairs. -
We iterate over each pair
(a, b)
:- The first interesting pair is
(2, 3)
. Sincea
is2
(ourkey
), we increment the counter forb
, which is3
:cnt[3]
becomes1
.mx
was0
, somx
is updated to1
, andans
is set to3
. - The next occurrence of
2
is in(2, 2)
. We increment the counter for2
:cnt[2]
becomes1
. Sincemx
is1
andcnt[2]
equalsmx
, nothing changes withmx
andans
. - We encounter
(2, 3)
again. Incrementing the counter for3
:cnt[3]
becomes2
.mx
is then updated to2
, andans
becomes3
. - Finally, we see
(2, 5)
. We increment the counter for5
:cnt[5]
becomes1
. Sincemx
is still higher (2), we do nothing.
- The first interesting pair is
-
After completion, the
Counter
objectcnt
contains:cnt = {3: 2, 2: 1, 5: 1}
ans
holds3
, andmx
holds2
. Thus, the most frequent number following2
is3
.
Therefore, the solution would return 3
as the target number that most frequently appears immediately after the key
in the array nums
.
Solution Implementation
1from collections import Counter
2from itertools import pairwise
3
4class Solution:
5 def mostFrequent(self, nums, key):
6 # Initialize a counter to keep track of the occurrences after the key
7 count = Counter()
8
9 # Variables to keep track of the element with the highest frequency
10 most_frequent_element = 0
11 max_frequency = 0
12
13 # Iterate over the pairwise elements of nums to identify pairs where the first element is the key
14 for current, following in pairwise(nums):
15 # Check if the current element is equal to the key
16 if current == key:
17 # Increment the counter for the following element
18 count[following] += 1
19 # Check if the count of the following element is greater than the max frequency seen so far
20 if max_frequency < count[following]:
21 # Update the max frequency and the most frequent element
22 max_frequency = count[following]
23 most_frequent_element = following
24
25 # Return the element that appears most frequently immediately after the key
26 return most_frequent_element
27```
28
29Note that the `pairwise` function is used here which requires Python 3.10 or newer. If an older version of Python is used, one could create pairs using a loop or by using the `zip` function like so:
30
31```python
32# Example for pairwise utility using zip when itertools.pairwise isn't available
33def custom_pairwise(iterable):
34 a, b = tee(iterable)
35 next(b, None)
36 return zip(a, b)
37
1class Solution {
2
3 // Finds the number that appears most frequently immediately after the key in an array
4 public int mostFrequent(int[] nums, int key) {
5 // Array to store the counts of numbers
6 int[] count = new int[1001]; // Assuming the input numbers will not exceed 1000
7 int answer = 0; // Variable to store the most frequent number following the key
8 int maxCount = 0; // Variable to store the max frequency
9
10 // Loop through the array, but not including the last element
11 // because it cannot be followed by any other number
12 for (int i = 0; i < nums.length - 1; ++i) {
13 // Check if the current element is the key
14 if (nums[i] == key) {
15 // Increment the count of the number that follows the key
16 count[nums[i + 1]]++;
17
18 // If the new count is greater than the current maxCount, update maxCount and answer
19 if (maxCount < count[nums[i + 1]]) {
20 maxCount = count[nums[i + 1]];
21 answer = nums[i + 1];
22 }
23 }
24 }
25
26 // Return the number that is most frequently observed after the key
27 return answer;
28 }
29}
30
1class Solution {
2public:
3 // Function to find the most frequent element in the array following the 'key' element
4 int mostFrequent(vector<int>& nums, int key) {
5 int count[1001] = {}; // Initialize an array to store frequency of elements with all values set to 0
6 int answer = 0; // Variable to store the most frequent element
7 int maxFrequency = 0; // Variable to store the maximum frequency
8
9 // Iterate through the array, except the last element
10 for (int i = 0; i < nums.size() - 1; ++i) {
11 // Check if the current element is equal to the 'key'
12 if (nums[i] == key) {
13 // Increment the frequency of the element following the 'key'
14 int nextElement = nums[i + 1];
15 count[nextElement]++;
16
17 // Update the answer if the next element's updated frequency is greater than the maxFrequency
18 if (maxFrequency < count[nextElement]) {
19 maxFrequency = count[nextElement];
20 answer = nextElement;
21 }
22 }
23 }
24
25 // Return the most frequent element that follows the 'key'
26 return answer;
27 }
28};
29
1function mostFrequent(nums: number[], key: number): number {
2 // Initialize an array to count frequencies of elements following the key
3 const frequencyCounter: number[] = new Array(1001).fill(0);
4
5 // Variables for tracking the most frequent element and its frequency
6 let mostFrequentElement = 0;
7 let maxFrequency = 0;
8
9 // Iterate through the array, but stop one element before the end
10 for (let i = 0; i < nums.length - 1; ++i) {
11 // Check if the current element is the key
12 if (nums[i] === key) {
13 // Increment the frequency count of the element after the key
14 const target = nums[i + 1];
15 frequencyCounter[target]++;
16
17 // If the new frequency count is greater than the max frequency,
18 // update the most frequent element and the max frequency
19 if (maxFrequency < frequencyCounter[target]) {
20 maxFrequency = frequencyCounter[target];
21 mostFrequentElement = target;
22 }
23 }
24 }
25
26 // Return the element that appeared most frequently after the key
27 return mostFrequentElement;
28}
29
Time and Space Complexity
The time complexity of the provided code is O(n)
where n
is the length of the input list nums
. This is because we are iterating through the list exactly once with pairwise(nums)
, and the operations within the loop are performed in constant time.
The space complexity is O(u)
where u
is the number of unique elements that come immediately after key
in the list nums
. The worst case for space complexity occurs when every element following key
is unique, in which case the Counter
will store each unique element. However, on average, the space used by the Counter
would probably be less than n
because not all elements in nums
would be unique or follow the key
.
Learn more about how to find time and space complexity quickly using problem constraints.
Consider the classic dynamic programming of fibonacci numbers, what is the recurrence relation?
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!