给定一个无序的整数类型数组,求最长的连续元素序列的长度。
例如:
给出的数组为[1000, 4, 2000, 1, 3, 2],
最长的连续元素序列为[1, 2, 3, 4]. 返回这个序列的长度:4
你需要给出时间复杂度在O(n)之内的算法
public int longestConsecutive(int[] num) { Set<Integer> set = new HashSet<Integer>(); for(int n : num){ set.add(n); } int max = 1; for(int n : num){ if(set.remove(n)){ int val = n; int sum = 1; int val_small = val - 1; int val_big = val + 1; while(set.remove(val_small)){ sum++; val_small--; } while(set.remove(val_big)){ val_big++; sum++; } max = Math.max(max, sum); } } return max; }
import java.util.*; public class Solution { public int longestConsecutive(int[] num) { HashMap<Integer,Boolean> map = new HashMap<Integer,Boolean>(); int max = -1; int count = 0; for (Integer integer : num) { map.put(integer,false); } Iterator<Integer> iterator = map.keySet().iterator(); while(max<map.size()/2&&iterator.hasNext()){ Integer integer = iterator.next(); if(map.get(integer)) continue;////该integer访问过了; int temp = integer; //先找左边 while(map.containsKey(integer)){ map.put(integer, true);//该integer访问过了; integer = integer-1; count++; } integer = temp+1; //找右边 while(map.containsKey(integer)){ map.put(integer, true);//该integer访问过了; integer = integer+1; count++; } if(count>max){ max = count; } count = 0; } return max; } }HashMap元素存取的时间复杂度一般是O(1)的范围
class Solution { public: int longestConsecutive(vector<int> &num) { unordered_set<int> myset(num.begin(),num.end()); int res=1; for(int current:num) { if(myset.find(current)==myset.end()) continue; myset.erase(current); int prev=current-1,post=current+1; while(myset.find(prev)!=myset.end()) { myset.erase(prev--); } while(myset.find(post)!=myset.end()) { myset.erase(post++); } res=max(res,post-prev-1); } return res; } };
class Solution { //主要思路是用set存储num中的元素(去除重复元素不影响求解结果), //然后寻找每个元素左右邻居数,删除,记录删除过程中最大连续长度 public: int longestConsecutive(vector<int> &num) { if(num.size()==0) return 0; set<int> st(num.begin(),num.end()); int count = 1; for(int i=0;i<num.size();i++) { int tmp = num[i]; if(st.count(tmp)==0) continue; int l=tmp-1,r=tmp+1; while(st.count(l)) st.erase(l--); while(st.count(r)) st.erase(r++); count = max(count,r-l-1); } return count; } };
idea:
code:
#include <bits/stdc++.h> class Solution { public: int longestConsecutive(vector<int> &num) { map<int, int> mp; int ans = 0; for (int i = 0; i < num.size(); i++){ if (!mp.count(num[i])){ mp[num[i]] = 1; int left = 0, right = 0; if (mp.count(num[i]-1)){ // 左边有序列 left = mp[num[i]-1]; //记录左边序列长度 mp[num[i]] += left; //当前序列长度加上左边序列长度 } if (mp.count(num[i]+1)){ right = mp[num[i]+1]; //记录右边序列长度 mp[num[i]] += right; //当前序列长度加上右边序列长度 } mp[num[i]+right] = mp[num[i]]; //更新序列最右端元素的序列长度 mp[num[i]-left] = mp[num[i]]; ////更新序列最左端元素的序列长度 if (mp[num[i]] > ans) ans = mp[num[i]]; } } return ans; }; };
class Solution { public: int longestConsecutive(vector<int> &num) { set<int> Set(num.begin(),num.end()); int result = 1; for(int x:num) { if(Set.find(x) == Set.end()) continue; Set.erase(x); int l=x-1,r=x+1; while(Set.find(l) != Set.end()) Set.erase(l--); while(Set.find(r) != Set.end()) Set.erase(r++); result = max(result,r-l-1); } return result; } };
class Solution { public int longestConsecutive(int[] nums) { //create a hashset, and put nums in it Set<Integer> tempSet = new HashSet<>(); for(int element : nums){ tempSet.add(element); } //set a flag int record = 0 ; //traverse the hashset for(int number : tempSet){ //judge the exixtense of x-1 if(!tempSet.contains(number-1)){ int currentNum = number; int currentRecord=1; //if not contain x-1 ,calculate the currentRecord while(tempSet.contains(currentNum+1)){ currentRecord+=1; currentNum+=1; } //keep the record always the Max one record=Math.max(record,currentRecord); } } return record; } }
class Solution { public: int longestConsecutive(vector<int> &num) { priority_queue<int> Q; for(auto elm:num) Q.push(elm); int n = 1, max_len = 1; while(!Q.empty()){ int t = Q.top(); Q.pop(); cout << t << endl; if(!Q.empty() && Q.top() == t-1){ n += 1; max_len = max(max_len, n); } if(!Q.empty() && Q.top()!=t-1){ max_len = max(max_len, n); n = 1; } } return max_len; } };
import java.util.*; public class Solution { /** * 本来先排序再遍历一遍即可,时间复杂度O(nlogn) * 但是题目要求O(n),就只能时间换空间,通过哈希表 * 记录数组元素,然后遍历数组,去哈希表中找这个元 * 素所处的连续序列,得到序列长度,这里注意已经找 * 到的元素从哈希表中去除,不需要再次查找了,所有 * 元素只会被遍历两次,时间复杂度O(n) */ public int longestConsecutive(int[] nums) { Set<Integer> set = new HashSet<>(nums.length); for(int num:nums){ set.add(num); } int max = 0; for(int num:nums){ while(set.remove(num)){ int left = num, right = num; while(set.remove(left-1)) left--; while(set.remove(right+1)) right++; max = Math.max(max, right-left+1); } } return max; } }
class Solution { public: int longestConsecutive(vector<int> &num) { if(num.size()==0) return 0; map<int,int> book; int i,res=0; for(i=0;i<num.size();i++) book[num[i]]=1; for(i=0;i<num.size();i++){ int number=num[i],l,r; if(!book.count(number)) continue; book.erase(number); for(r=number+1;book.count(r);book.erase(r),r++); for(l=number-1;book.count(l);book.erase(l),l--); res=max(res,r-l-1); } return res; } };
首先将所有的元素记录在一个哈希表当中,然后从左到右依次遍历数组,假设遍历到元素cur,从cur开始向外扩张,记录能扩张出去的最大长度。每访问一个元素就将该元素在哈希表中抹去,这样可以保证每个元素插入一次、删除一次,时间复杂度为O(N)。如果每次访问不删除元素,也没有问题,但是时间复杂度就退化为O(N^2)。
class Solution {
public:
int longestConsecutive(vector<int> &num) {
if(num.size() < 2)
return num.size();
unordered_set<int> sets(num.begin(), num.end());
int res = 0;
for(auto cur : num)
{
if(!sets.count(cur))
continue;
int left = cur;
int right = cur;
sets.erase(cur);
while(sets.count(left-1))
{
sets.erase(--left);
}
while(sets.count(right+1))
{
sets.erase(++right);
}
res = max(res, right - left + 1);
}
return res;
}
};
class Solution { public: int longestConsecutive(vector<int> &num) { priority_queue<int> prique; for (unsigned int i = 0; i < num.size(); ++i) { prique.push(num[i]); } int sum = 1; int pre = prique.top(); prique.pop(); int cur = 0; int curSum = 1; while (!prique.empty()) { cur = prique.top(); if (cur == pre-1) { ++curSum; pre = cur; } else if (cur == pre) { ; } else { if (curSum > sum) { sum = curSum; } curSum = 1; pre = cur; } prique.pop(); } if (curSum > sum) { sum = curSum; } return sum; } };
import java.util.*; public class Solution { /** * 1.先把数字放到一个集合中,拿到一个数字,就往其两边搜索,得到包含这个数字的最长串, * 2.并且把用过的数字从集合中移除(因为连续的关系,一个数字不会出现在两个串中)。 * 3.最后比较当前串是不是比当前最大串要长,是则更新。如此继续直到集合为空。 * @param num * @return */ public int longestConsecutive(int[] num) { if(num==null||num.length==0) return 0; int res=1; Set<Integer> numbers=new HashSet<>(); for(int val:num){ numbers.add(val); } while(!numbers.isEmpty()){ int len=1; Iterator iterator=numbers.iterator(); int cur=(int)iterator.next(); numbers.remove(cur); int left=cur-1,right=cur+1; while (numbers.contains(left)){ len++; numbers.remove(left--); } while(numbers.contains(right)){ len++; numbers.contains(right++); } res=len>res?len:res; } return res; } }
import java.util.*; public class Solution {
class Solution { public: int longestConsecutive(vector<int> &num) { int len = num.size(); sort(num.begin(),num.end()); int max = 1; int cnt = 1; for(int i = 1; i < len; i++) { if(num[i-1]+1 == num[i]) cnt++; else if(num[i-1] == num[i]) //注意重复元素 ; else { if(cnt > max) max = cnt; cnt =1; } } if(cnt > max) max = cnt; return max; } };
//用散列表,首先将数字都映射到散列表上,然后,对于每个数字,找到后就删除,然后向两边 //同时搜,只要搜到了就删除,最后求出长度。哈希表搜是O(1),因为每个数字只会添加一次, //删除一次,所以复杂度是O(n) class Solution { public: int longestConsecutive(vector<int> &num) { unordered_set<int> st(num.begin(),num.end()); int ans=0; for(auto v:num){ if(st.find(v)==st.end()) continue; int l=v,r=v; st.erase(v); while(st.find(r+1)!=st.end()) st.erase(++r); while(st.find(l-1)!=st.end()) st.erase(--l); ans=max(r-l+1,ans); } return ans; } };
import java.util.HashMap; public class Solution { //利用map的查找时间为o(1)的特性,拿空间换时间 public int longestConsecutive(int[] num) { if(num==null||num.length==0){ return 0; } if(num.length==1){ return 1; } HashMap<Integer,Boolean>map=new HashMap<>(); for(int i=0;i<num.length;++i){//将数组里的数存储进map map.put(num[i],true); } int pre;//当前数的前一个数 int curr;//当前数 int post;//后一个数 int max=1;//暂时的最大连续值 int maxmax=max;//我们记录的当前最大的连续值 for(int i=0;i<num.length;++i){ if(map.get(num[i])==true){//还未被访问 curr=num[i]; pre=num[i]-1; post=num[i]+1; while(map.containsKey(pre)){//一直找前面那个数 map.put(pre,false);//置值为false,下次不用再访问 max++;//最大连续数加一 pre--;//前面的那个数的数值减一 } while(map.containsKey(post)){//同上 map.put(post,false); max++; post++; } if(max>maxmax){//两个循环结束后,判断当前的最大连续值是否大于咱们存储的那个最大连续值 maxmax=max; } max=1;//置max为1 } } return maxmax; } }
public int longestConsecutive (int[] num) { // write code here int count = 1; if(num.length == 0){ return 0; } Set<Integer> set = new HashSet<>(); for(int n : num){ set.add(n); } for(int i = 0 ; i < num.length; i++){ int temp = num[i]; if(!set.contains(num[i])){ continue; } int l = temp - 1; int r = temp + 1; while(set.contains(l)){ set.remove(l--); } while(set.contains(r)){ set.remove(r++); } count = Math.max(count, r - l - 1); } return count; }