哎,这题又不会做,想了好久,还是想不出来,最长连续的数的长度,首先想到的肯定是排序,O(nlogn),不过题目要求是O(n),
于是又想到用hash的思想,类似数组记数的方式,不过即便不考虑存的空间的话,因为给定的数的大小并不在一定的范围之内,
所以最后的时间复杂度会是O(max - min),max是最大的数,min是最小的数,还是不满足题目的要求。
其实思考一下题目,所谓连续的数,只需要记录一段连续的数的最小的数和最大的数即可,当时也想到了这个,不过下意识的想法是用数组来存每个数所在的连续段,
这样每个数还是都要往回查找是否可以扩展前面某个连续段,感觉复杂度是O(n2)了,所以放弃了这个想法。
做不出来,无奈只好看别人的方法了,参考了peking2的解法(http://blog.sina.com.cn/s/blog_b9285de20101iqar.html),很巧妙的利用了set,
不过感觉也不能完全算是O(n)的呀,因为set的插入、删除操作并不是O(1),而是O(logn),实际复杂度应该是O(log(n!))呀,实际具体和O(n)的差距是多少,还很难评估!
1 class Solution { 2 public: 3 set<int> store; 4 int consecute(int n, bool direct) { 5 int count = 0; 6 while (store.count(n)) { 7 ++count; 8 store.erase(n); 9 if (direct) 10 n--; 11 else 12 n++; 13 } 14 return count; 15 } 16 int longestConsecutive(vector<int> &num) { 17 // Start typing your C/C++ solution below 18 // DO NOT write int main() function 19 int res = 0; 20 if (num.size() == 0) { 21 return res; 22 } 23 store.clear(); 24 for (int i = 0; i < num.size(); i++) { 25 store.insert(num[i]); 26 } 27 for (int i = 0; i < num.size(); i++) { 28 if (store.count(num[i])) { 29 res = max(res, (consecute(num[i], true) + consecute(num[i] + 1, false))); 30 } 31 } 32 return res; 33 } 34 };
其实用记录每个数所在的连续段的范围(最小值,最大值)也是可以的,可以利用map<int, pair<int, int> >来每个数的对应范围。
然后遇到可以扩展区间的数时更新区间范围即可。同样也参考了peking2的代码(http://blog.sina.com.cn/s/blog_b9285de20101i09x.html),
不过他的代码有个bug,遇到重复的数应该忽略。
1 class Solution { 2 public: 3 map<int, pair<int, int> > section; 4 int longestConsecutive(vector<int> &num) { 5 // Start typing your C/C++ solution below 6 // DO NOT write int main() function 7 section.clear(); 8 int start = 0; 9 int end = 0; 10 for (int i = 0; i < num.size(); i++) { 11 int k = num[i]; 12 map<int, pair<int, int> >::iterator it = section.find(k); 13 if (it != section.end()) { 14 continue; 15 } 16 else { 17 section.insert(make_pair(k, pair<int, int>(k, k))); 18 } 19 it = section.find(k - 1); 20 if (it != section.end()) { 21 section[k].first = (it->second).first; 22 } 23 it = section.find(k + 1); 24 if (it != section.end()) { 25 section[k].second = (it->second).second; 26 } 27 it = section.find(section[k].first); 28 if (it != section.end()) { 29 (it->second).second = section[k].second; 30 } 31 it = section.find(section[k].second); 32 if (it != section.end()) { 33 (it->second).first = section[k].first; 34 } 35 if (section[k].second - section[k].first > end - start) { 36 start = section[k].first; 37 end = section[k].second; 38 } 39 } 40 return (end - start + 1); 41 } 42 };