414. Third Maximum Number 第三大的数
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/
@TOC
题目地址:https://leetcode.com/problems/third-maximum-number/description/
题目描述
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.
题目大意
找出一个数组中第三大的数字,如果不存在的话,就返回最大数字。
解题方法
替换最大值数组
最基本的方法,找到最大值,然后每次把最大值移除,这样重复三次就得到了第三大的值。
class Solution(object):
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
def setMax(nums):
_max = max(nums)
for i, num in enumerate(nums):
if num == _max:
nums[i] = float('-inf')
return _max
max1 = setMax(nums)
max2 = setMax(nums)
max3 = setMax(nums)
return max3 if max3 != float('-inf') else max(max1, max2)
使用set
用set去算,set的时间复杂度是O(n)。set的remove()方法可以去除某个值,不过每次只能去除一个。
class Solution(object):
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_set = set(nums)
if len(nums_set) < 3:
return max(nums_set)
nums_set.remove(max(nums_set))
nums_set.remove(max(nums_set))
_max = max(nums_set)
return _max
这个方法的C++版本如下:
class Solution {
public:
int thirdMax(vector<int>& nums) {
set<int> s;
for (int num : nums) {
s.insert(num);
}
if (s.size() < 3) {
return maxset(s);
}
s.erase(maxset(s));
s.erase(maxset(s));
return maxset(s);
}
private:
int maxset(set<int> &s) {
int res = INT_MIN;
for (int c : s) {
res = max(res, c);
}
return res;
}
};
原来C++也有求最大值函数叫做max_element(),参数是起始和结束位置,返回的是指针。
class Solution {
public:
int thirdMax(vector<int>& nums) {
set<int> s;
for (int num : nums) {
s.insert(num);
}
if (s.size() < 3) return *max_element(s.begin(), s.end());
s.erase(*max_element(s.begin(), s.end()));
s.erase(*max_element(s.begin(), s.end()));
return *max_element(s.begin(), s.end());
}
};
三个变量
维护三个变量分别保存最大、次大、第三大的值,只需要遍历一次数组,找到这个数字和三个变量的大小关系,就能对应的更新对应的值。
为了去重,elif里面写了当前的Num要处于开区间内。
class Solution(object):
def thirdMax(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# s1 > s2 > s3
s1, s2, s3 = float('-inf'), float('-inf'), float('-inf')
for num in nums:
if num > s1:
s1, s2, s3 = num, s1, s2
elif num < s1 and num > s2:
s2, s3 = num, s2
elif num < s2 and num > s3:
s3 = num
return s3 if s3 != float('-inf') else s1
这个方法的C++写法如下,为什么需要使用long long 呢?因为当第三大的数字是INT_MIN的话,你如果把三个数字都初始化成了INT_MIN就没法判断了。
class Solution {
public:
int thirdMax(vector<int>& nums) {
long long s1, s2, s3;
s1 = s2 = s3 = LLONG_MIN;
for (int num : nums) {
if (num > s1) {
s3 = s2;
s2 = s1;
s1 = num;
} else if (num < s1 && num > s2) {
s3 = s2;
s2 = num;
} else if (num < s2 && num > s3) {
s3 = num;
}
}
return s3 != LLONG_MIN ? s3 : s1;
}
};
日期
2018 年 2 月 4 日 2018 年 11 月 27 日 —— 最近的雾霾太可怕