题解:
这道题如果不看时间复杂度那是挺容易的,一个排序就解决了,但是限制到O(n)还是要点方法才能解出来的:
方法1:
- 如果元素的个数<=2,直接返回最大的值即可。
- 如果元素的个数>3,首先找出最大的(注意:可能有多个),把最大的数标记为
INT_MAX
,然后把这个最大的数记录下来为:realMaxV
,然后找出第二大的(也可以有多个),把次大的也标记为INT_MAX
,最后找出第三大的,可能出现一种情况,>=3个数中不存在第三大的数,所以第三个循环max还是等于INT_MIN
(也就是进入不了if语句),那么就输出realMaxV
,如果max != realMaxV
也就说明有第三大的值,输出即可。
可能以为这样就已经对了,但是实际上还有一种情况没考虑到:
可能有元素的值等于INT_MIN
,比如测试点: [1,2,-2147483648],那正好我的第三个循环就以为没有第三大的值了,输出了2,但实际上INT_MIN
就是第三大的值,所以在里面加一个判断语句,如果出现了INT_MIN
,那么第三大的值肯定是这个数(而且也是最小的)。
代码(方法1):
class Solution {
public:
int thirdMax(vector<int>& nums) {
if(nums.size() <= 2)
{
if(nums.size() == 1)
return nums[0];
else
return max(nums[0],nums[1]);
}
else
{
int maxV = INT_MIN;
// 1. 找出最大的
for(int i = 0; i < (int)nums.size(); i++)
{
if(nums[i] > maxV)
{
maxV = nums[i];
}
}
for(int i = 0; i < (int)nums.size(); i++)
{
if(nums[i] == maxV)
{
nums[i] = INT_MAX;
}
}
int realMaxV = maxV;
// 2. 找出次大的
maxV = INT_MIN;
for(int i = 0; i < (int)nums.size(); i++)
{
if(nums[i] != INT_MAX && nums[i] > maxV)
{
maxV = nums[i];
}
}
for(int i = 0; i < (int)nums.size(); i++)
{
if(nums[i] == maxV)
{
nums[i] = INT_MAX;
}
}
// 3. 找出第三大的
maxV = INT_MIN;
for(int i = 0; i < (int)nums.size(); i++)
{
if(nums[i] != INT_MAX && nums[i] > maxV)
{
maxV = nums[i];
}
if(nums[i] == INT_MIN)
{
return INT_MIN;
}
}
if(maxV == INT_MIN)
{
// 出现这种情况也就是:找不到第三大的数,全部数都是INT_MAX,虽然元素个数>=3,但是有重复的
return realMaxV;
}
return maxV;
}
}
};
方法2:
直接用一个set
即可,遍历nums的元素到set中,然后就出来了,只是相比上述上面更加耗时间、空间,直接看代码。
class Solution {
set <int> s;
public:
int thirdMax(vector<int>& nums) {
for(int i = 0; i < (int)nums.size(); i++)
{
s.insert(nums[i]);
}
int sLen = s.size();
if(sLen <= 2)
{
int maxV = INT_MIN;
for(set<int>::iterator it = s.begin(); it != s.end(); it++)
{
maxV = max(maxV,*it);
}
return maxV;
}
int cnt = 0; int The3MaxV;
for(set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cnt++;
if(cnt == sLen-2)
{
The3MaxV = *it;
}
}
return The3MaxV;
}
};