题目要求时间复杂度为O(n),由此可见,排序肯定不行的。在O(n)时间下第一个想到的就是哈希,这里可用Map解决。怎么样找到连续的序列呢,可以用到并查集。连续的序列为一个集合,在用个结构存放每个集合中元素个数就行了。
并查集具体的操作过程:每遍历到一个数,就看集合中是否存在它前一个数,若存在,则他的父节点就为前一个数,按照这个思路排下去,每个集合中都是连续的。
本来这些都可用数组搞定,但是题目的数据范围为1e9,数组开不了那么大,只能用map了。
下面给出Leetcode和本地编译器的代码。
Leetcode
/*
* @lc app=leetcode.cn id=128 lang=cpp
*
* [128] 最长连续序列
*/
// @lc code=start
#define INF 0x3f3f3f3f
struct deNum{
int value = INF;//初始化为INF,因为默认的为0,但是又有0这个元素
};
struct deV{
int cnt = 1;
};
map<int,deNum> mp;//父节点Map key-》value(本节点,父节点)
map<int,deV> Max;//个数Map key-》value(本节点,本节点所在集合个数)
int findfa(int x)
{
if(x != mp[x].value){
mp[x].value = findfa(mp[x].value);
}
return mp[x].value;
}
void Union(int x,int y)
{
int fax = findfa(x);
int fay = findfa(y);
if(fax != fay){
mp[fax].value = fay;
Max[fay].cnt += Max[fax].cnt;
}
//printf("x : %d, fa: %d\n",x,mp[x].value);
}
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
for(int i = 0; i < nums.size(); i++){
mp[nums[i]].value = nums[i];
Max[nums[i]].cnt = 1;
}
for(int i = 0; i < nums.size(); i++){
if(mp[nums[i] - 1].value != INF && mp[nums[i]].value != INF){//验证集合中是否存在前一个数,存在,则合并
Union(nums[i],nums[i] - 1);
}
}
int MAX = 0;
map<int,deV>::iterator iter;
for(iter = Max.begin(); iter != Max.end(); iter++){
MAX = max(MAX,iter->second.cnt);
}
mp.clear();
Max.clear();
return MAX;
}
};
// @lc code=end
编译器代码 可用来debug
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#include <bitset>
#include <sstream>
#define LL long long
#define ULL unsigned long long
#define mod 99997867
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
using namespace std;
const int maxn = 1e3 + 5;
const int NUM = 1e6 + 5;
int n,m;
int dis[NUM];
struct deNum{
int value = INF;
};
struct deV{
int cnt = 1;
};
map<int,deNum> mp;
map<int,deV> Max;
int findfa(int x)
{
if(x != mp[x].value){
mp[x].value = findfa(mp[x].value);
}
return mp[x].value;
}
void Union(int x,int y)
{
int fax = findfa(x);
int fay = findfa(y);
if(fax != fay){
mp[fax].value = fay;
Max[fay].cnt += Max[fax].cnt;
}
}
int main()
{
int a[maxn];
scanf("%d",&n);
for(int i = 0; i < n; i++) scanf("%d",&a[i]);
for(int i = 0; i < n; i++) mp[a[i]].value = a[i],Max[nums[i]].cnt = 1;
for(int i = 0; i < n; i++){
if(mp[a[i] - 1].value != INF && mp[a[i]].value != INF){
Union(a[i],a[i] - 1);
}
}
for(int i = 0; i < n; i++) findfa(a[i]);
int MAX = 0;
map<int,deV>::iterator iter;
for(iter = Max.begin(); iter != Max.end(); iter++){
MAX = max(iter->second.cnt,MAX);
}
printf("%d\n",MAX);
return 0;
}
/*
6
100 2 200 1 3 4
10
0 3 7 2 5 8 4 6 0 1
*/