Longest Consecutive Sequence

来源:互联网 发布:lol请检查网络连接 编辑:程序博客网 时间:2024/06/07 15:33

题目中要求时间复杂度O(n),所以不能通过简单的排序来解决问题,但我试了下先排序再做的效果,很不错,至少以很漂亮的速度AC了,哈哈。。。

先贴一个“投机取巧”先排序的版本,要注意去除重复元素的影响

class Solution {public:    int longestConsecutive(vector<int> &num) {        int n=num.size();        if(n==0)        {            return 0;        }        sort(num.begin(),num.end());        vector<int>::iterator itr=unique(num.begin(),num.end());        n=itr-num.begin();        vector<int> dp(n,1);        int max=1;        for(int i=1;i<n;++i)        {            if(num[i]==(num[i-1]+1))            {                dp[i]=dp[i-1]+1;            }            if(dp[i]>max)            {                max=dp[i];            }        }        return max;    }};

思来想去还是没有找到O(n)的解法,最终参考了论坛大神的解法,算是学习了一下,贴上大神的代码:

int longestConsecutive(vector<int> num) {    unordered_map<int,int> m;    int ret = 0;    for(auto & n: num){        //it is in the middle of some consecutive sequence OR we can say it is already visited earlier        //therefore it does not contribute to a longer sequence        if(m[n]) continue;         //we cannot find adjacent sequences to n, therefore it is a single element sequence by itself        if(m.find(n-1) == m.end() && m.find(n+1) == m.end()){ //             ret = max(ret, m[n] = 1);            continue;        }        //found a sequence at n+1        //you may wonder what if the sequence at n+1 contains element n?        //It it contains n, when we add the length by 1 using m[n+1]+1, it is wrong, right?        //However it is not possible, because if sequence at n+1 contains n, m[n] must have been visited earlier        //we checked that using if(m[n]) continue; here m[n] is not yet visited;        //therefore sequence m[n+1] is always on right side, we can safely extend the length by 1        if(m.find(n-1)==m.end()){             //we want to maintain the TWO boundaries of the sequence            //the new length of the sequence is the original length m[n+1] incremented by 1            //left boundary m[n] = m[n+1] +1;            //right boundary m[n+m[n+1]] = m[n+1]+1;            //why n+m[n+1]? it is equal to m[n+1]+(n+1)-1             //meaning the old left boundary n+1 plus the old length m[n+1] minus 1            //e.g. for sequence 3,4,5,6 m[3] = 4, and right boundary 6 = 3+m[3]-1 (here n+1 == 3);            int r = m[n] = m[n+m[n+1]] = m[n+1]+1;            ret = max(ret, r);            continue;        }        //this is similar to the above case just extend to the right        if(m.find(n+1)==m.end()){            int r = m[n] = m[n-m[n-1]] = m[n-1]+1;            ret = max(ret,r);            continue;        }        //here, we found both sequences at n+1 and n-1, for reasons we explained,        //the sequences have no overlap.        //Now, we just need to add the length of current element n (which is 1) to both left and right boundaries        //the new length will be :          //old length of left sequence (m[n-1]) + old length of right sequence (m[n+1]) + 1        //We also need to mark m[n] as visited, here we can either mark it with 1 or the new length;        int r = m[n-m[n-1]] = m[n+m[n+1]] = 1+ m[n+1]+ m[n-1];        m[n] = 1; //basically we just need to mark m[n] as any non-zero number        // or we can write        //int r = m[n] = m[n-m[n-1]] = m[n+m[n+1]] = 1+ m[n+1]+ m[n-1];        ret = max(ret,r);    }    return ret;}


0 0