[LeetCode] Third Maximum Number 第三大的數
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.
這道題讓我們求陣列中第三大的數,如果不存在的話那麼就返回最大的數,題目中說明了這裡的第三大不能和第二大相同,必須是嚴格的小於,而並非小於等於。這道題並不是很難,如果知道怎麼求第二大的數,那麼求第三大的數的思路都是一樣的。那麼我們用三個變數first, second, third來分別儲存第一大,第二大,和第三大的數,然後我們遍歷陣列,如果遍歷到的數字大於當前第一大的數first,那麼三個變數各自錯位賦值,如果當前數字大於second,小於first,那麼就更新second和third,如果當前數字大於third,小於second,那就只更新third,注意這裡有個坑,就是初始化要用長整型long的最小值,否則當陣列中有INT_MIN存在時,程式就不知道該返回INT_MIN還是最大值first了,參見程式碼如下:
解法一:
class Solution { public: int thirdMax(vector<int>& nums) { long first = LONG_MIN, second = LONG_MIN, third = LONG_MIN; for (int num : nums) { if (num > first) { third = second; second = first; first= num; } else if (num > second && num < first) { third = second; second = num; } else if (num > third && num < second) { third = num; } } return (third == LONG_MIN || third == second) ? first : third; } };
下面這種方法的時間複雜度是O(nlgn),不符合題目要求,純粹是拓寬下思路哈,利用了set的自動排序和自動去重複項的特性,很好的解決了問題,對於遍歷到的數字,加入set中,重複項就自動去掉了,如果此時set大小大於3個了,那麼我們把set的第一個元素去掉,也就是將第四大的數字去掉,那麼就可以看出set始終維護的是最大的三個不同的數字,最後遍歷結束後,我們看set的大小是否為3,是的話就返回首元素,不是的話就返回尾元素,參見程式碼如下:
解法二:
class Solution { public: int thirdMax(vector<int>& nums) { set<int> s; for (int num : nums) { s.insert(num); if (s.size() > 3) { s.erase(s.begin()); } } return s.size() == 3 ? *s.begin() : *s.rbegin(); } };
參考資料: