標籤:longest consecutive leetcode
其實網上關於leetcode的題目的答案已經相當多了,這也是為啥我自己不把每道題目都貼出來的原因,覺得分析得沒人好,代碼也沒別人的精簡。不過,這道題目看到網上有不少做法跟實際要求的O(n)複雜度不太符合,所以特別粘貼出來,也正好記錄下自己的一些想法。
說實話,在第二遍做這道題目的時候,我還是沒能夠把最為完善的解法想出來,能夠想到的是利用hash表以序列值為key,1(只是簡單做個標記)為val,把序列儲存起來,利用hash表O(1)的插入,查詢複雜度來滿足題目複雜度要求。這道題目的解法其實不難,就是遍曆num中的每個元素,然後分別以num[i] - 1和num[i] + 1的順序掃描,看是否能構成連續的序列。這道題目有兩個地方需要注意,看到別人使用set,map來做,雖然原理是對的,但是由於從容器實現角度來看,它們都是基於紅/黑樹狀結構來實現的,其插入,尋找複雜度為O(log n),故其實並不滿足題目要求。此外,還有一點也很重要,就是每次掃描到連續序列的時候,必須把對應的元素從hash表中刪除,這樣才能夠保證每個元素只被掃描一次,否則複雜度也並非O(n)(假如不刪除表中元素提交的話,會time limit exceed)。注意到以上兩點後,相信寫代碼實現就不難了。此外,我自己還犯過一個錯,就是遍曆元素的時候,一開始直接對hash表進行遍曆,結果刪除元素的時候會對迭代器產生影響而導致程式崩潰,後來改成對num的元素進行遍曆就可以了,其實本來就該這麼做,一時間沒想通。。。好了,能AC的代碼如下,可能寫的比較醜陋,望輕拍~
class Solution {public: int longestConsecutive(vector<int> &num) { if (num.size() <= 1) return num.size(); unordered_map<int, int> table; for (int i = 0; i < num.size(); i++) table.insert(make_pair(num[i], 1)); int maxLen = 0; int len; for (int i = 0; i < num.size(); i++) { len = 1; if (table[num[i]] == 1) { for (int j = num[i] - 1; ; j--) { if (table.find(j) != table.end()) { len++; table.erase(j); } else break; } for (int j = num[i] + 1; ; j++) { if (table.find(j) != table.end()) { len++; table.erase(j); } else break; } if (len > maxLen) maxLen = len; } } return maxLen; }};