问题
思路
由于没有排序,并且要求在O(N)时间内完成。
考虑哈希表做映射,连续的序列一定在连续的部分命中。当然,如果用c写这个思路可以。但是如果c++用map做,只能是考虑前后两个元素的值是否相差1,从而来判断是否时连续序列。
代码(c++实现)
// c++ version
class Solution {
public:
int longestConsecutive(std::vector<int>& nums) {
int sz = nums.size();
if(!sz)
return 0;
std::map< int, bool > mapper;
for( int i = 0; i < sz; ++i )
{
mapper[nums[i]] = true;
}
typedef std::map<int, bool>::const_iterator const_iter;
const_iter b = mapper.begin();
const_iter e = mapper.end();
int max = 0;
int cnt = 0;
int pre = b->first - 1;
while( b != e )
{
if( b->first == pre + 1 )
++cnt;
else
{
if( cnt > max )
max = cnt;
cnt = 1;
}
pre = b->first;
++b;
}
if( cnt > max )
max = cnt;
return max;
}
};
思路1
上面的代码时间复杂度不符合要求:
std::map< int, bool > mapper;
for( int i = 0; i < sz; ++i )
{
mapper[nums[i]] = true;
}
这一段代码相当于一个排序,map查询,插入,删除的复杂度是o(logn),所以,循环之后是o(nlogn)。这里是问题。
看到一个新的思路,也是非常的赞啊。
[Longest Consecutive Sequence leetcode]
还是考虑连续的元素,从某一点开始,分别向元素值-1和元素值+1的地方走,看能走到哪里。如果一个元素之前被走到了,本次没有必要再走,因为之前走到这,如果可以走的更远,之前就可以走了。只需把所有元素放到集合里面就好了。
代码1
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int sz = nums.size();
if(!sz) return 0;
unordered_set<int> mapper(nums.begin(), nums.end());
int ans = 0;
for(int i = 0; i < sz; ++i){
if( mapper.find(nums[i]) != mapper.end() ){
mapper.erase(nums[i]);
// move to left
int left_max = 0;
int left = nums[i] - 1;
while( mapper.find(left) != mapper.end() ){
mapper.erase(left);
left_max++;
left--;
}
// move to right
int right_max = 0;
int right = nums[i] + 1;
while( mapper.find(right) != mapper.end() ){
mapper.erase(right);
right_max++;
right++;
}
int cur = left_max + right_max + 1;
if(cur > ans) ans = cur;
}
}
return ans;
}
};