Given an integer array nums
, return the third distinct maximum number in this array. If the third maximum does not exist, return the maximum number.
Example 1:
Input: nums = [3,2,1] Output: 1 Explanation: The first distinct maximum is 3. The second distinct maximum is 2. The third distinct maximum is 1.
Example 2:
Input: nums = [1,2] Output: 2 Explanation: The first distinct maximum is 2. The second distinct maximum is 1. The third distinct maximum does not exist, so the maximum (2) is returned instead.
Example 3:
Input: nums = [2,2,3,1] Output: 1 Explanation: The first distinct maximum is 3. The second distinct maximum is 2 (both 2's are counted together since they have the same value). The third distinct maximum is 1.
Constraints:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
Follow up: Can you find an
O(n)
solution?This problem asks to find the third distinct maximum number in an integer array. If the third maximum doesn't exist, return the maximum number.
The most efficient approach is a single-pass algorithm using a constant amount of extra space. We maintain three variables to track the largest three distinct numbers encountered so far: m1
, m2
, and m3
.
Initialization: Initialize m1
, m2
, and m3
to the smallest possible integer value (-∞
or Long.MIN_VALUE
depending on the language). This ensures that any number in the input array will be larger than the initial values.
Iteration: Iterate through the input array nums
. For each number num
:
num
is equal to any of m1
, m2
, or m3
, skip it (we only want distinct numbers).num
is greater than m1
(the current largest), we shift m1
to m2
, m2
to m3
, and assign num
to m1
. Otherwise, if num
is greater than m2
(the second largest), we shift m2
to m3
and assign num
to m2
. Finally, if num
is greater than m3
(the third largest), we assign num
to m3
.Result: After iterating through the entire array, if m3
is still its initial value (meaning no third distinct maximum was found), return m1
(the maximum number). Otherwise, return m3
(the third distinct maximum number).
m1
, m2
, m3
) regardless of the input array size.Python:
import sys
class Solution:
def thirdMax(self, nums: List[int]) -> int:
m1 = m2 = m3 = -sys.maxsize -1 #Using -sys.maxsize -1 for negative infinity in Python.
for num in nums:
if num in [m1, m2, m3]:
continue
if num > m1:
m3 = m2
m2 = m1
m1 = num
elif num > m2:
m3 = m2
m2 = num
elif num > m3:
m3 = num
return m3 if m3 != -sys.maxsize -1 else m1
Java:
class Solution {
public int thirdMax(int[] nums) {
long m1 = Long.MIN_VALUE;
long m2 = Long.MIN_VALUE;
long m3 = Long.MIN_VALUE;
for (int num : nums) {
if (num == m1 || num == m2 || num == m3) {
continue;
}
if (num > m1) {
m3 = m2;
m2 = m1;
m1 = num;
} else if (num > m2) {
m3 = m2;
m2 = num;
} else if (num > m3) {
m3 = num;
}
}
return (int) (m3 != Long.MIN_VALUE ? m3 : m1);
}
}
C++:
class Solution {
public:
int thirdMax(vector<int>& nums) {
long long m1 = LLONG_MIN, m2 = LLONG_MIN, m3 = LLONG_MIN;
for (long long num : nums) {
if (num == m1 || num == m2 || num == m3) continue;
if (num > m1) {
m3 = m2;
m2 = m1;
m1 = num;
} else if (num > m2) {
m3 = m2;
m2 = num;
} else if (num > m3) {
m3 = num;
}
}
return (m3 == LLONG_MIN) ? m1 : m3;
}
};
Go:
func thirdMax(nums []int) int {
m1, m2, m3 := math.MinInt64, math.MinInt64, math.MinInt64
for _, num := range nums {
if num == m1 || num == m2 || num == m3 {
continue
}
if num > m1 {
m3, m2, m1 = m2, m1, num
} else if num > m2 {
m3, m2 = m2, num
} else if num > m3 {
m3 = num
}
}
if m3 == math.MinInt64 {
return m1
}
return m3
}
These code snippets all implement the same single-pass algorithm, differing only in syntax and specific language features for representing the smallest possible integer value. They all achieve O(n) time complexity and O(1) space complexity.