题目内容如下: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).
这个题目需要考虑到INT_MIN的问题。
c++解法
解法1:
在discuss中发现的解法,使用了set,代码十分简洁明了。 耗时16ms。时间复杂度O(n)空间复杂度O(1)
class Solution {
public:
int thirdMax(vector<int>& nums) {
set<int> top3;
for (num:nums){
if (top3.insert(num).second && top3.size()>3)
top3.erase(top3.begin());
}
return top3.size()==3 ? *top3.begin() : *top3.rbegin();
}
};
这种方法中top3.insert(num)返回的是一个pair类型,第一个参数是一个迭代器,第二个参数是true or false。解法完全利用了set的特性。晚上专门写一篇set的博客进行介绍。
解法2:
解法2是一种很朴素的解法,用三个int类型存储top3的数据,maxNum 单独存储最大的数据。bool isIntMin用来判断是否有INT_MIN的数据出现。耗时6ms,时间复杂度O(n)空间复杂度O(1)。
有一个很奇怪的现象,在本解法中,不使用maxNum 单独存储最大数据,而是直接用firstNum 当做最大数据,把第10行maxNum = max(maxNum, num);这一行删除,把最后27行29行return中的maxNum改成firstNum ,按理说应该是计算量减小了,但是最后的运行时间却变成了9ms。百思不得其解。
class Solution {
public:
int thirdMax(vector<int>& nums) {
//unordered_set<int> v(nums.begin(), nums.end());
int maxNum, num, firstNum, secondNum, thirdNum;
firstNum = secondNum = thirdNum = maxNum = INT_MIN;
bool isIntMin=false;
for(auto it = nums.begin() ; it != nums.end() ; ++it) {
num = *it;
maxNum = max(maxNum, num);
if (num == INT_MIN) isIntMin = true;
if (num == firstNum || num == secondNum || num == thirdNum) continue;
if (num > firstNum) {
thirdNum = secondNum;
secondNum = firstNum;
firstNum = num;
}
else if (num > secondNum) {
thirdNum = secondNum;
secondNum = num;
}
else if (num > thirdNum) {
thirdNum = num;
}
}
if (isIntMin == true)
return secondNum == INT_MIN ? maxNum : thirdNum;
else
return secondNum == INT_MIN || thirdNum == INT_MIN ? maxNum : thirdNum;
}
};
python解法
使用float(‘-inf’)表示负无穷。这是Python解法的关键吧
解法1
思路和c++解法2类似,只是使用了Python中的list在存数据。时间复杂度O(n),空间复杂度O(1),耗时52ms
class Solution(object):
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dicts = [float('-inf')]*3
for num in nums:
if num in dicts: continue
if num > dicts[0] :
dicts[2] = dicts[1]
dicts[1] = dicts[0]
dicts[0] = num
elif num > dicts[1] :
dicts[2] = dicts[1]
dicts[1] = num
elif num > dicts[2] :
dicts[2] = num
return dicts[0] if dicts[1] == float('-inf') or dicts[2] == float('-inf') else dicts[2]
解法2
在discuss中发现的解法。使用了heapq 模块的堆排序来解决问题。代码简洁明了。 耗时45ms,空间复杂度O(1),时间复杂度O(n)
class Solution(object):
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l = [float('-inf')] * 3
[heapq.heappushpop(l, n) for n in nums if n > l[0] and n not in l]
return l[0] if l[0] != float('-inf') else max(l)
解法3
使用set来完成。思路也很简单,把nums装入set。如果set的len()小于3则返回max,反之删除两次max后再返回max
时间复杂度O(n),空间复杂度O(n)耗时38 ms
class Solution(object):
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums = set(nums)
if len(nums) < 3:
return max(nums)
nums.remove(max(nums))
nums.remove(max(nums))
return max(nums)