githubEdit

08. Next Element with Greater Frequency

βœ… GFG solution to the Next Element with Greater Frequency problem: find the closest element to the right with higher frequency using monotonic stack technique. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

Given an array arr[] of integers, for each element, find the closest (distance wise) to its right that has a higher frequency than the current element. If no such element exists, return -1 for that position.

The goal is to efficiently find the next element with greater frequency for each position in the array while maintaining optimal time and space complexity.

πŸ“˜ Examples

Example 1

Input: arr[] = [2, 1, 1, 3, 2, 1]
Output: [1, -1, -1, 2, 1, -1]
Explanation: Frequencies: 1 β†’ 3 times, 2 β†’ 2 times, 3 β†’ 1 time.
For arr[0] = 2, the next element 1 has a higher frequency β†’ 1.
For arr[1] and arr[2], no element to the right has a higher frequency β†’ -1.
For arr[3] = 3, the next element 2 has a higher frequency β†’ 2.
For arr[4] = 2, the next element 1 has a higher frequency β†’ 1.
For arr[5] = 1, no elements to the right β†’ -1.

Example 2

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^5$

  • $1 \le \text{arr}[i] \le 10^5$

βœ… My Approach

The optimal approach uses a Monotonic Stack combined with Frequency Mapping to efficiently find the next element with greater frequency:

Forward Stack + Map

  1. Pre-compute Frequencies:

    • Build a frequency map to store count of each element in the array.

    • This allows O(1) frequency lookup for any element.

  2. Initialize Data Structures:

    • Use a stack to maintain indices of elements in decreasing order of their frequencies.

    • Initialize result array with -1 values.

  3. Process Elements Left to Right:

    • For each element at index i, compare its frequency with elements in the stack.

    • While stack is not empty and current element's frequency > frequency of element at stack top:

      • Pop the index from stack and set result[popped_index] = current_element.

    • Push current index onto stack.

  4. Stack Invariant:

    • Stack maintains indices in decreasing order of frequencies.

    • When we find an element with higher frequency, it becomes the answer for all elements in stack with lower frequencies.

  5. Final Result:

    • Elements remaining in stack have no next greater frequency element (already -1 in result).

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. Each element is pushed and popped from the stack at most once, and frequency lookup is O(1).

  • Expected Auxiliary Space Complexity: O(n), where n is the size of the array. We use O(n) space for the frequency map, O(n) for the stack in worst case, and O(n) for the result array.

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ Reverse Traversal Approach

πŸ’‘ Algorithm Steps:

  1. Traverse array from right to left

  2. Maintain stack of elements with their frequencies

  3. For each element, pop smaller frequencies

  4. Find next greater frequency element directly

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(n) - for stack and frequency map

βœ… Why This Approach?

  • Direct computation of next greater element

  • Cleaner logic for finding next element

  • Better intuition for stack-based problems

πŸ“Š 3️⃣ Frequency Array Optimization

πŸ’‘ Algorithm Steps:

  1. Use array for frequency when value range is small

  2. Avoid hash map overhead for better performance

  3. Maintain monotonic stack of indices

  4. Process elements left to right

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(max - min) - for frequency array

βœ… Why This Approach?

  • Faster array access than hash map

  • Better cache locality

  • Optimal for constrained value ranges

πŸ“Š 4️⃣ Deque-based Sliding Window

πŸ’‘ Algorithm Steps:

  1. Use deque to maintain elements in frequency order

  2. Slide through array maintaining frequency invariant

  3. Quick access to next greater frequency element

  4. Efficient for specific input patterns

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(n) - for deque and frequency map

βœ… Why This Approach?

  • Deque provides more flexibility than stack

  • Can access both ends efficiently

  • Alternative data structure approach

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

πŸ” Forward Stack + Map

🟒 O(n)

🟑 O(n)

πŸš€ Standard monotonic stack

πŸ’Ύ Hash map overhead

πŸ”Ί Reverse Stack Traversal

🟒 O(n)

🟑 O(n)

πŸ”§ Direct next element finding

πŸ’Ύ Stack stores value-frequency pairs

⏰ Frequency Array

🟒 O(n)

🟑 O(range)

πŸš€ Fastest access, cache friendly

πŸ”„ Limited to small value ranges

πŸ“Š Deque-based Approach

🟒 O(n)

🟑 O(n)

⚑ Flexible data structure

πŸ”§ Slight overhead vs stack

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

⚑ General purpose, all inputs

πŸ₯‡ Forward Stack + Map

β˜…β˜…β˜…β˜…β˜…

πŸ“Š Small value range (≀ 10⁡)

πŸ₯ˆ Frequency Array

β˜…β˜…β˜…β˜…β˜†

🎯 Educational, easier to understand

πŸ₯‰ Reverse Stack Traversal

β˜…β˜…β˜…β˜…β˜†

πŸš€ Competitive programming

πŸ… Forward Stack Traversal

β˜…β˜…β˜…β˜…β˜…

πŸ§‘β€πŸ’» Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated