Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
