您的位置:首页 > 产品设计 > UI/UE

[leetcode] Longest Consecutive Sequence

2016-03-13 00:20 429 查看
题目:给定一个无序数组,求最长的连续序列的长度。

例如:给定
[100,4,200,1,3,2]
,则最长的连续序列为[1,2,3,4], 返回4即可。

要求:算法时间复杂度为O(n).

思路一: 看到题目,最直观的想法就是先排序,然后遍历一遍有序数组使用类似动态规划的思想求解最长连续序列。但又要求时间复杂度为O(n),所以就想到了基数排序。基数排序基本上是线性时间复杂度。int型一般为4个字节,可以将int当做无符号整数从低字节到高字节进行基数排序,则相当于有4个关键字,每个关键字(一个字节)取值范围是0~255。由于最高位是符号位(0表示正,1表示负),故排好之后的序列是:从小到大的正数在前,从小到大的负数在后,将负数部分提到正数部分前面,则变为整体有序。具体代码如下:

class Solution {
public:

void BucketSort(vector<int>& nums){
int n = nums.size();
int r = sizeof(int);  // 一般为4个字节
vector<int> tmp;
int c[256];
for(int i=0; i<r; ++i){
tmp = nums;
// 计数排序
            memset(c,0,sizeof(c));
for(int j=0; j<n; ++j){
int idx = (tmp[j]>>(i*8)) & (0x000000ff);
++ c[idx];
}
c[255] = n - c[255];
for(int i = 254; i>=0; --i){
c[i] = c[i+1] - c[i];
}
for(int j=0; j<n; ++j){
int idx = (tmp[j]>>(i*8)) & (0x000000ff);
nums[c[idx]++] = tmp[j];
}
}
tmp = nums;
int k = n;
for(int i=0; i<n; ++i){
if(tmp[i] < 0){
k = i;
break;
}
}
int j = 0;
for(int i=k; i<n; ++i){ // 负数部分移至前面
nums[j++] = tmp[i];
}
for(int i=0; i<k; ++i){ // 正数部分置于其后
nums[j++] = tmp[i];
}
}

int longestConsecutive(vector<int>& nums) {
int ret = 0;
if(nums.empty())   return 0;
BucketSort(nums);
ret = 1;
int tmp = 1;
for(int i=1; i<nums.size(); ++i){
if(nums[i] == nums[i-1] + 1){
++ tmp;
ret = max(ret, tmp);
}else if(nums[i] == nums[i-1]){  // 注意数组中有相同元素

}else{
tmp = 1;
}
}
return ret;
}
};


思路二:看了题目的标签是并查集(Union Find),就是说要将连续的元素置于同一分组中。当访问到某个元素e时,就去查看e+1和e-1在不在数组中,然后分别顺次向+1和-1的方向查找,直到找不到下一个相邻的元素为止;同时要在查找的过程中标记数组中已经访问过的元素。由于哈希查找的时间约为O(1),故整体时间复杂度约为O(n)。代码如下:

class Solution {
public:
// 类似并查集分组:访问到一个元素时,检查其相邻元素在不在
int longestConsecutive(vector<int>& nums) {
if(nums.empty())   return 0;
unordered_map<int,int> map;
for(int i=0; i<nums.size(); ++i){
map[nums[i]] = i+1;
}
unordered_map<int,int>::iterator it;
int ret = 1, count = 0;
for(it = map.begin(); it != map.end(); ++ it){
if(it->second == 0)   continue;
++ count;
map[it->first] = 0;
int tmp = it->first;
while(map.find(--tmp) != map.end()){
++ count;
map[tmp] = 0;
}
tmp = it->first;
while(map.find(++tmp) != map.end()){
++ count;
map[tmp] = 0;
}
ret = max(ret, count);
count = 0;
}
return ret;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: