JavaScript - Finding the third maximum number in an array

In this article, we will learn to find the third maximum unique number in an array of JavaScript, or the largest number if there are fewer than three unique values. We will be using three methods: a single-pass approach for efficiency, a sorting method to identify the number after removing duplicates, and a combination of Set and Max-Heap for optimal handling of large datasets.

Problem Statement

Given an array of integers, find the third maximum unique number. If the array contains fewer than three unique numbers, return the largest number in the array.

Input:

const nums = [7, 2, 5, 9, 9, 5, 3];

Output:

The third maximum unique number is 5.

The goal is to find the number efficiently, ideally in O(n) time complexity with a single iteration.

Using Single-Pass Approach

The single-pass method iterates through the array once while keeping track of the top three unique numbers. This approach offers the best time complexity of O(n).

Algorithm Steps:

  • Initialize Variables: Set first, second, and third to -Infinity to handle any number in the array
  • Update Maximums: Iterate through the array and update the maximum values accordingly
  • Return the Result: Return the third maximum if found; otherwise, return the largest number

Example

const arr = [1, 5, 23, 3, 676, 4, 35, 4, 2];

const findThirdMax = (arr) => {
    let [first, second, third] = [-Infinity, -Infinity, -Infinity];
    
    for (let el of arr) {
        // Skip duplicates
        if (el === first || el === second || el === third) {
            continue;
        }
        
        if (el > first) {
            [first, second, third] = [el, first, second];
        } else if (el > second) {
            [second, third] = [el, second];
        } else if (el > third) {
            third = el;
        }
    }
    
    return third !== -Infinity ? third : first;
};

console.log("Third maximum number:", findThirdMax(arr));
Third maximum number: 23

Using Sorting

Sorting is a straightforward approach. After removing duplicates with a Set and sorting in descending order, we can directly access the third unique element.

Example

function thirdMaxSort(arr) {
    // Remove duplicates using a Set
    const uniqueArr = [...new Set(arr)];
    
    // Sort the array in descending order
    uniqueArr.sort((a, b) => b - a);
    
    // Check if the array has at least three elements
    return uniqueArr.length >= 3 ? uniqueArr[2] : uniqueArr[0];
}

// Example usage
const nums = [3, 2, 1, 4, 4];
console.log("Third maximum number:", thirdMaxSort(nums));
Third maximum number: 2

Using Set and Max-Heap

This approach uses a priority queue (max-heap) to efficiently retrieve the third largest number. We first eliminate duplicates with a Set, then use a max-heap to get the top three elements.

Example

class MaxHeap {
    constructor() {
        this.heap = [];
    }

    push(val) {
        this.heap.push(val);
        this._heapifyUp();
    }

    pop() {
        if (this.heap.length === 0) return undefined;
        if (this.heap.length === 1) return this.heap.pop();
        
        const max = this.heap[0];
        this.heap[0] = this.heap.pop();
        this._heapifyDown();
        return max;
    }

    _heapifyUp() {
        let index = this.heap.length - 1;
        while (index > 0) {
            let parentIndex = Math.floor((index - 1) / 2);
            if (this.heap[parentIndex] >= this.heap[index]) break;
            [this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];
            index = parentIndex;
        }
    }

    _heapifyDown() {
        let index = 0;
        const length = this.heap.length;
        
        while (true) {
            let leftChild = 2 * index + 1;
            let rightChild = 2 * index + 2;
            let largest = index;

            if (leftChild < length && this.heap[leftChild] > this.heap[largest]) {
                largest = leftChild;
            }

            if (rightChild < length && this.heap[rightChild] > this.heap[largest]) {
                largest = rightChild;
            }

            if (largest === index) break;

            [this.heap[largest], this.heap[index]] = [this.heap[index], this.heap[largest]];
            index = largest;
        }
    }
}

function thirdMaxHeap(arr) {
    const uniqueSet = new Set(arr);
    const maxHeap = new MaxHeap();

    // Insert elements into the heap
    for (const num of uniqueSet) {
        maxHeap.push(num);
    }

    // Pop the first three elements
    let firstMax = maxHeap.pop();
    let secondMax = maxHeap.pop();
    let thirdMax = maxHeap.pop();

    // If there are fewer than 3 unique elements, return the largest one
    return thirdMax !== undefined ? thirdMax : firstMax;
}

// Example usage
const nums = [7, 2, 5, 9, 9, 5, 3];
console.log("Third maximum number:", thirdMaxHeap(nums));
Third maximum number: 5

Comparison

Method Time Complexity Space Complexity Best Use Case
Single-Pass Approach O(n) O(1) Large datasets where efficiency matters
Sorting Approach O(n log n) O(n) Small to medium arrays, simple implementation
Max-Heap Approach O(n log n) O(n) When heap operations are needed elsewhere

Conclusion

The single-pass approach is the most efficient solution with O(n) time and O(1) space complexity. Use sorting for simpler implementations, and consider the heap approach when working with priority queue operations in larger applications.

Alshifa Hasnain
Alshifa Hasnain

Converting Code to Clarity

Updated on: 2026-03-15T23:19:00+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements