1. 程式人生 > >領釦(LeetCode)第三大的數 個人題解

領釦(LeetCode)第三大的數 個人題解

給定一個非空陣列,返回此陣列中第三大的數。如果不存在,則返回陣列中最大的數。要求演算法時間複雜度必須是O(n)。

示例 1:

輸入: [3, 2, 1]

輸出: 1

解釋: 第三大的數是 1.

示例 2:

輸入: [1, 2]

輸出: 2

解釋: 第三大的數不存在, 所以返回最大的數 2 .

示例 3:

輸入: [2, 2, 3, 1]

輸出: 1

解釋: 注意,要求返回第三大的數,是指第三大且唯一出現的數。
存在兩個值為2的數,它們都排第二。

第一次遇到這個題目,想到的辦法就是定義三個數,第一大,第二大,第三大,然後依次判斷。這個辦法行之有效。但是最開始沒寫出來正確答案,因為沒有考慮到去重的問題。
由於考慮到去重,所以我又想到用集合來解決,把陣列放到集合裡面去,放的時候就去掉重複的元素,最後得到一個沒有重複的集合。然後再對集合進行排序,判斷是否有第三大的數,最後得到正確答案。
但是這樣做,演算法的複雜度就達到了O(n2)的級別。雖然能得到正確答案,也能通過領釦的測試,成功AC,但是速度之低令人髮指,只打敗了提交的1%的人。
程式碼如下:
 1 class Solution {
 2     public int thirdMax(int[] nums) {
 3         Vector v=new Vector();
 4         for (int i : nums) {
 5             if(!v.contains(i))
 6                 v.add(i);
 7         }
 8         v.sort(null);
 9         if(v.size()>=3)
10             return (int) v.get(v.size()-3);
11 else 12 return (int) v.get(v.size()-1); 13 } 14 }
然後重新思考最開始的做法,他的演算法複雜度是O(n),然後參考了相關的程式碼,發現可以使用Integer這個JAVA內封裝好的類,設定值為null,來表示未被放置過的數。同時,加了忽略掉重複的元素邏輯,成功AC。
程式碼如下:
 1 class Solution {
 2     public int thirdMax(int[] nums) {
 3         Integer fmax = null, smax = null
, tmax = null; 4 for (int i : nums) { 5 if ((fmax != null && fmax == i) || (smax != null && smax == i) || (tmax != null && tmax == i)) 6 continue; 7 if (fmax == null || i > fmax) { 8 tmax = smax; 9 smax = fmax; 10 fmax = i; 11 } else if (smax == null || i > smax) { 12 tmax = smax; 13 smax = i; 14 } else if (tmax == null || i > tmax) { 15 tmax = i; 16 } 17 } 18 return tmax == null ? fmax : tmax; 19 } 20 }