Question
Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n).
Example 1:
Input: [3, 2, 1]
Output: 1
Explanation: The third maximum is 1.
Example 2:
Input: [1, 2]
Output: 2
Explanation: The third maximum does not exist, so the maximum (2) is returned instead.
Example 3:
Input: [2, 2, 3, 1]
Output: 1
Explanation: Note that the third maximum here means the third maximum distinct number.
Both numbers with value 2 are both considered as second maximum.
Solution 1
用两个标识符表示,第二大的数和第三大的数是否已经赋值。
class Solution {
public:
int thirdMax(vector<int>& nums) {
if (nums.size() == 1)
return nums[0];
if (nums.size() == 2)
return max(nums[0], nums[1]);
long one = nums[0];
long two = LONG_MIN;
long three = LONG_MIN;
bool two_flag = true;
bool three_flag = true;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > one) {
if (one > two) {
if (two > three) {
three = two;
three_flag = false;
}
two = one;
two_flag = false;
}
one = nums[i];
}
else if ((two_flag || nums[i] > two) && nums[i] != one) {
if (two > three) {
three = two;
three_flag = false;
}
two = nums[i];
two_flag = false;
}
else if ((three_flag || nums[i] > three) && nums[i] != one && nums[i] != two) {
three = nums[i];
three_flag = false;
}
}
if (!three_flag)
return three;
else
return one;
}
};
Solution 2
用STL set,因为set中最多有3个元素,因此操作都是常量时间的,这样就可以保证总的时间是O(n),而且set会自动排序,底层实现是二叉排序树,因为有利于比较。
class Solution {
public:
int thirdMax(vector<int>& nums) {
set<int> s;
for (int i = 0; i < nums.size(); i++) {
if (s.size() < 3)
s.insert(nums[i]);
else {
set<int>::iterator it = s.begin();
if (s.find(nums[i]) == s.end() && (nums[i] > *(it) || nums[i] > *(++it) || nums[i] > *(++it)) ) {
s.erase(it);
s.insert(nums[i]);
}
}
}
if (s.size() == 3)
return *(s.begin());
else
return *(s.rbegin());
}
};