Facebook Pixel

2190. Most Frequent Number Following Key In an Array

EasyArrayHash TableCounting
Leetcode Link

Problem Description

You have an integer array nums (0-indexed) and an integer key that appears in the array.

Your task is to find which number appears most frequently immediately after key in the array.

Specifically, for each unique integer target in nums, count how many times target appears right after key. This means counting the number of valid indices i where:

  • i is between 0 and nums.length - 2 (inclusive)
  • nums[i] == key
  • nums[i + 1] == target

Return the target value that has the maximum count. The problem guarantees that there will be exactly one target with the maximum count (no ties).

For example, if nums = [1, 100, 200, 1, 100] and key = 1, you would check what comes after each occurrence of 1:

  • At index 0: 1 is followed by 100
  • At index 3: 1 is followed by 100

So 100 appears 2 times after key = 1, making it the answer.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem asks us to find the most frequent number that appears immediately after a specific key value. This is essentially a counting problem where we need to track consecutive pairs.

The key insight is that we need to examine every consecutive pair (nums[i], nums[i+1]) in the array. Whenever the first element of a pair equals key, we should count the second element as a potential answer.

To solve this efficiently, we can use a hash table (or Counter in Python) to keep track of how many times each number appears after key. As we traverse the array:

  • Check each consecutive pair
  • When we find nums[i] == key, increment the count for nums[i+1]
  • Keep track of the maximum count seen so far and which number has that count

This approach works because:

  1. We only need one pass through the array
  2. The hash table allows us to count occurrences of each target in O(1) time
  3. By maintaining the maximum count during traversal, we avoid needing a second pass to find the answer

The pairwise function in Python makes this even cleaner by automatically giving us consecutive pairs (a, b) from the array, where we can simply check if a == key and then count b.

Solution Approach

The solution uses a hash table to count occurrences and a single traversal to find the answer.

Data Structures Used:

  • Counter (hash table): To store the count of each target that appears after key
  • Two variables: mx to track the maximum count, and ans to store the target with maximum count

Implementation Steps:

  1. Initialize the data structures:

    • Create a Counter object cnt to store frequency counts
    • Set ans = 0 (to store the final answer) and mx = 0 (to track maximum frequency)
  2. Traverse consecutive pairs:

    • Use pairwise(nums) to iterate through all consecutive pairs (a, b) in the array
    • This gives us pairs like (nums[0], nums[1]), (nums[1], nums[2]), etc.
  3. Count targets after key:

    • For each pair (a, b):
      • If a == key, then b is a target that follows key
      • Increment the count: cnt[b] += 1
  4. Update maximum on the fly:

    • After incrementing cnt[b], check if this new count exceeds mx
    • If mx < cnt[b]:
      • Update mx = cnt[b] (new maximum count)
      • Update ans = b (the target with this maximum count)
  5. Return the result:

    • After traversing all pairs, ans contains the target with the maximum count

Time Complexity: O(n) where n is the length of nums, as we traverse the array once.

Space Complexity: O(k) where k is the number of unique targets that appear after key, for storing the counts in the hash table.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [2, 2, 2, 2, 3] and key = 2.

Step 1: Initialize data structures

  • cnt = {} (empty counter)
  • ans = 0 (will store our answer)
  • mx = 0 (tracks maximum frequency)

Step 2: Process consecutive pairs

We'll examine each consecutive pair (a, b):

Pair 1: (2, 2) at indices (0, 1)

  • a = 2 equals key = 2
  • So b = 2 is a target that follows key
  • Update: cnt[2] = 1
  • Check maximum: cnt[2] = 1 > mx = 0
  • Update: mx = 1, ans = 2

Pair 2: (2, 2) at indices (1, 2)

  • a = 2 equals key = 2
  • So b = 2 is a target that follows key
  • Update: cnt[2] = 2
  • Check maximum: cnt[2] = 2 > mx = 1
  • Update: mx = 2, ans = 2

Pair 3: (2, 2) at indices (2, 3)

  • a = 2 equals key = 2
  • So b = 2 is a target that follows key
  • Update: cnt[2] = 3
  • Check maximum: cnt[2] = 3 > mx = 2
  • Update: mx = 3, ans = 2

Pair 4: (2, 3) at indices (3, 4)

  • a = 2 equals key = 2
  • So b = 3 is a target that follows key
  • Update: cnt[3] = 1
  • Check maximum: cnt[3] = 1 > mx = 3? ✗
  • No update needed (3 still has the maximum count)

Step 3: Return the result

  • Final counter: cnt = {2: 3, 3: 1}
  • The number 2 appears 3 times after key = 2
  • The number 3 appears 1 time after key = 2
  • Return ans = 2

The answer is 2 because it appears most frequently (3 times) immediately after the key value 2.

Solution Implementation

1class Solution:
2    def mostFrequent(self, nums: List[int], key: int) -> int:
3        # Dictionary to count occurrences of elements that follow the key
4        count_map = {}
5      
6        # Variables to track the result and maximum frequency
7        result = 0
8        max_frequency = 0
9      
10        # Iterate through consecutive pairs in the array
11        for i in range(len(nums) - 1):
12            current_element = nums[i]
13            next_element = nums[i + 1]
14          
15            # Check if current element matches the key
16            if current_element == key:
17                # Increment count for the element following the key
18                if next_element not in count_map:
19                    count_map[next_element] = 0
20                count_map[next_element] += 1
21              
22                # Update result if we found a more frequent target
23                if max_frequency < count_map[next_element]:
24                    max_frequency = count_map[next_element]
25                    result = next_element
26      
27        return result
28
1class Solution {
2    public int mostFrequent(int[] nums, int key) {
3        // Array to store frequency count of target values (range: 1-1000)
4        int[] frequencyCount = new int[1001];
5      
6        // Variable to store the answer (most frequent target)
7        int mostFrequentTarget = 0;
8      
9        // Variable to track the maximum frequency encountered
10        int maxFrequency = 0;
11      
12        // Iterate through the array, checking each pair of adjacent elements
13        for (int i = 0; i < nums.length - 1; i++) {
14            // Check if current element matches the key
15            if (nums[i] == key) {
16                // Increment frequency count for the target (next element after key)
17                int targetValue = nums[i + 1];
18                frequencyCount[targetValue]++;
19              
20                // Update the most frequent target if current frequency is higher
21                if (frequencyCount[targetValue] > maxFrequency) {
22                    maxFrequency = frequencyCount[targetValue];
23                    mostFrequentTarget = targetValue;
24                }
25            }
26        }
27      
28        // Return the most frequent target value
29        return mostFrequentTarget;
30    }
31}
32
1class Solution {
2public:
3    int mostFrequent(vector<int>& nums, int key) {
4        // Array to count occurrences of each target value (constraint: values are 1-1000)
5        int count[1001]{};
6      
7        // Track the result (most frequent target) and its maximum frequency
8        int result = 0;
9        int maxFrequency = 0;
10      
11        // Iterate through the array, stopping before the last element
12        // since we need to check nums[i+1]
13        for (int i = 0; i < nums.size() - 1; ++i) {
14            // Check if current element matches the key
15            if (nums[i] == key) {
16                // Increment count for the target (next element after key)
17                int targetValue = nums[i + 1];
18                count[targetValue]++;
19              
20                // Update result if this target appears more frequently
21                if (count[targetValue] > maxFrequency) {
22                    maxFrequency = count[targetValue];
23                    result = targetValue;
24                }
25            }
26        }
27      
28        return result;
29    }
30};
31
1/**
2 * Finds the most frequent element that appears immediately after the key element in the array
3 * @param nums - The input array of numbers
4 * @param key - The key element to search for
5 * @returns The most frequent element that appears after the key element
6 */
7function mostFrequent(nums: number[], key: number): number {
8    // Create a frequency counter array with size based on the maximum value in nums
9    // This array tracks how many times each number appears after the key
10    const frequencyCounter: number[] = Array(Math.max(...nums) + 1).fill(0);
11  
12    // Initialize variables to track the answer and maximum frequency
13    let mostFrequentTarget: number = 0;  // The element that appears most frequently after key
14    let maxFrequency: number = 0;         // The maximum frequency encountered
15  
16    // Iterate through the array, stopping one element before the end
17    // since we need to check the next element
18    for (let i = 0; i < nums.length - 1; i++) {
19        // Check if current element matches the key
20        if (nums[i] === key) {
21            // Get the target element (the element immediately after the key)
22            const target: number = nums[i + 1];
23          
24            // Increment the frequency count for the target element
25            frequencyCounter[target]++;
26          
27            // Update the result if this target has a higher frequency than previous maximum
28            if (frequencyCounter[target] > maxFrequency) {
29                maxFrequency = frequencyCounter[target];
30                mostFrequentTarget = target;
31            }
32        }
33    }
34  
35    return mostFrequentTarget;
36}
37

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. The algorithm iterates through the array once using pairwise(nums), which generates n-1 pairs. For each pair, it performs constant-time operations: checking if a == key, updating the counter, and comparing/updating the maximum frequency.

The space complexity is O(M), where M represents the number of distinct elements that appear immediately after the key in the array. In the worst case, this could be all unique values that follow the key, which is bounded by the maximum value of elements in nums if we consider the counter stores at most M distinct integers. The Counter object stores the frequency of each target element that appears after key, and the additional variables (ans, mx) use O(1) space.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Off-by-One Error in Loop Range

A common mistake is iterating through the entire array without considering that we need to check pairs. If you iterate up to len(nums) instead of len(nums) - 1, you'll get an index out of bounds error when accessing nums[i + 1].

Incorrect:

for i in range(len(nums)):  # Goes up to len(nums) - 1
    if nums[i] == key:
        target = nums[i + 1]  # IndexError when i = len(nums) - 1

Correct:

for i in range(len(nums) - 1):  # Stops at len(nums) - 2
    if nums[i] == key:
        target = nums[i + 1]  # Safe access

2. Not Handling Empty or Single-Element Arrays

The code assumes there are at least two elements to form a pair. Edge cases with empty arrays or arrays with only one element could cause issues.

Solution: Add a guard clause at the beginning:

if len(nums) < 2:
    return 0  # or handle according to problem constraints

3. Incorrect Maximum Tracking

Some might try to find all counts first, then search for the maximum in a separate pass. This works but is less efficient and more error-prone.

Less Efficient Approach:

# First pass: count all
for i in range(len(nums) - 1):
    if nums[i] == key:
        count_map[nums[i + 1]] = count_map.get(nums[i + 1], 0) + 1

# Second pass: find maximum
result = 0
max_freq = 0
for target, count in count_map.items():
    if count > max_freq:
        max_freq = count
        result = target

Better Approach (as shown in solution): Update the maximum during the counting process itself, eliminating the need for a second pass.

4. Using Wrong Comparison Operator

When updating the maximum, using <= instead of < could potentially return a different target if multiple targets have the same maximum count (though the problem guarantees uniqueness).

Potentially Problematic:

if max_frequency <= count_map[next_element]:  # Uses <=
    max_frequency = count_map[next_element]
    result = next_element

Correct:

if max_frequency < count_map[next_element]:  # Uses <
    max_frequency = count_map[next_element]
    result = next_element

5. Forgetting to Initialize Dictionary Values

When using a regular dictionary instead of defaultdict or Counter, forgetting to initialize new keys leads to KeyError.

Incorrect:

count_map[next_element] += 1  # KeyError if next_element not in count_map

Correct:

if next_element not in count_map:
    count_map[next_element] = 0
count_map[next_element] += 1

Or use defaultdict:

from collections import defaultdict
count_map = defaultdict(int)
count_map[next_element] += 1  # Automatically initializes to 0
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

You are given an array of intervals where intervals[i] = [start_i, end_i] represent the start and end of the ith interval. You need to merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input.


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More