題目鏈接:最長連續序列
題目描述:給定一個未排序的整數數組,找出最長連續序列的長度。
要求算法的時間複雜度爲 O(n)。
示例:
輸入: [100, 4, 200, 1, 3, 2]
輸出: 4
解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度爲 4。
題目分析:關鍵點要求時間複雜度爲O(n),那麼排序啥的自然就不能用。先求出連續序列,然後找個最長的。這裏主要是藉助哈希去重表,如何達到O(n)的複雜度呢?在暴力枚舉的過程中,我們在對每個數尋找連續序列的過程中進行了很多重複的判斷,使用set可以把這些重複去掉,大大的簡化了複雜度。對於每個連續序列,我們從第一個數開始,依次往後,保證了每個序列的數只被遍歷一次,最後加起來是n。可以理解爲數組一共有a個序列組成,每個序列只遍歷了一次。
代碼:
class Solution {
public int longestConsecutive(int[] nums) {
if(nums.length == 0||nums.length==1) return nums.length;
HashSet<Integer> st = new HashSet<>();
for(int num:nums){
st.add(num);
}
int res = 0;
for(int num:st){
if(!st.contains(num-1)){//保證num是某個序列的開始
int cur = num;
int curLen = 1;
while(st.contains(cur+1)){//找這個序列的連續長度
cur+=1;
curLen+=1;
}
res = Math.max(res,curLen);//更新最大值
}
}
return res;
}
}
一開始我是使用的痛排序的算法,因爲桶排序的時間複雜度可以達到O(n),無非是以時間換空間的思想,但是桶排序比較頭疼的點就是存在溢出和邊界處理,是過不了所有用例的,這裏就當提供一種思路吧,後續再完善。。
class Solution {
public int solve(int maxNum,int[] bool){
maxNum = Math.abs(maxNum);
int res = 1,cur = 1;
for(int i = 0;i < maxNum;i++){
if(bool[i]==1&&bool[i+1]==1){
cur += 1;
res = Math.max(res,cur);
}else{
cur = 1;
}
}
return res;
}
public int longestConsecutive(int[] nums) {
if(nums.length == 0||nums.length==1) return nums.length;
int n = nums.length,res = 1;
int maxNum = 0,minNum = 0;
for(int i = 0;i < n;i++){
maxNum = Math.max(maxNum,nums[i]);
minNum = Math.min(minNum,nums[i]);
}
int[] bool = new int[maxNum+1];
int[] bool1 = new int[Math.abs(minNum)+1];
for(int i = 0;i < n;i++){
if(nums[i]>=0) bool[nums[i]]=1;
else bool1[Math.abs(nums[i])]=1;
}
int positive = solve(maxNum,bool);
int negtive = solve(minNum,bool1);
// System.out.println(positive+" "+negtive);
if(bool[0]==1&&bool[1]==1&&bool1[1]==1)
return positive+negtive;
else return Math.max(positive,negtive);
}
}
這裏我把正負數分開處理,其實可以合併到一個數組裏面,不想寫了😂😂😂