題目:
給定乙個未排序的整數陣列,找出最長連續序列的長度。要找連續序列的長度,從結果可以看出,主要是為了排序,排序之後,遍歷結果就可以進行連續長度的更新。要求演算法的時間複雜度為 o(n)。
示例:輸入: [100, 4, 200, 1, 3, 2]
輸出: 4
解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度為 4。
但是排序的演算法,即使快排的時間複雜度也有o(nlogn),不滿足要求。
這種時候一般就會想到借助雜湊表,也就是類似計數排序,先來試試,用陣列來做雜湊表,下標做nums[i]。
1. 找出最大最小值(考慮有負值),這樣就確定了雜湊表的size
2. 遍歷陣列,對應的值在雜湊表裡++;
3. 遍歷雜湊表,非 0 元素連續長度的最大值,進行更新。
class
solution
min=
-min;
int[
] bucket=
newint
[max+min+1]
;for
(int num: nums)
int ans=
0,temp=0;
int i=0;
while
(ians=math.
max(ans,temp)
; temp=0;
i++;}
return ans;
}}
提交之後給我當頭一棒:
最後執行的輸入:
[2147483646,-2147483647,0,2,2147483644,-2147483645,2147483645]
可以看到,涉及到了整型的最小值和最大值問題,如果直接計算要使用的 bucket 的長度,一定會溢位,並且如果輸入裡有 int 的最小值,取反之後也要處理溢位。
上一種做法是,全部存下來,再去判斷,而陣列按照元素大小是連續儲存的,這樣肯定會有很多空間的浪費。
但是雜湊的想法本身應該是沒有問題的,我們來想想這個過程如何優化。
換成使用hashset來儲存本來的元素,這樣第二次進行判斷的時候我們只要查詢當前的 nums[i] ,以及挨著他的元素 nums[i]++ 在不在 hashset 中,如果在的話就給結果ans++,並且一路繼續查詢,否則就重新開始。
判斷在不在的過程交給 contains() 方法來完成。
class
solution
int ans=0;
int count=0;
for(
int i=
0;i) ans=math.
max(ans,count)
; count=0;
}return ans;
}}
這種方法顯然是可以提交通過的(雖然時間複雜度達不到要求),但是重複的工作顯然還是集中在了查詢部分。
對於任何乙個元素,都在 set 裡,去查詢和他連續的數字的存在性,我們先不考慮查詢過程的時間複雜度。
假設陣列是 [1,2,3,4,5],對於1,已經查詢過一次,計算出連續長度為 5 ,之後對於 2,3,4,5 又進行了重複的操作,這樣最壞情況下時間複雜度總共就達到了內外的o(n2)。
事實上,對於每乙個連續序列而言,我們只希望判斷一次,也就是從這個子串行的最小位置開始。那麼**對於每乙個元素 num ,先判斷 num-1 是否存在,**就可以避免這種重複了。
修改後的**如下:
for
(int i=
0;i) ans=math.
max(ans,count)
; count=0;
}}
也就是只多加一行 if(!set.contains(num-1)){
這時候的時間複雜度又是多少呢?
首先用 o(n) 時間把陣列存入set;
遍歷陣列,每乙個元素,只有不存在 num-1 ,才會進入計數階段;這些處於各個連續序列開始位置的元素,都會進入一次,然後進行計數,總共正好組成了原陣列的長度。而其他的元素在判斷 num-1 存在之後不會進入計數的迴圈。因此時間複雜度還是 o(n) 。
所以總時間複雜度是o(n)。原因得益於hashmap本身的查詢方法時間複雜度是o(1),個人認為也不是嚴格意義的o(1),可以看看這篇部落格的原始碼分析:
hashmap底層原始碼分析
LeetCode 力扣 128 最長連續序列
給乙個陣列,求出連續的數字最多有多少個,時間複雜度要求是o n 首先想一下最直接的暴力破解。我們可以用乙個hashset把給的陣列儲存起來。然後再考慮陣列的每個數,比如這個數是n,然後看n 1在不在hashset中,然後再看n 2在不在,接下來n 3 n 4直到在hashset中找不到,記錄當前的長...
Leetcode128 題目總結 hard
the first missing positive 找第乙個丟失的整數 方法1 從1開始尋找正整數result 找到就把他交換到nums i 同時i回退到result 1,時間複雜度大於o n ac class solution else return result 方法2 對每乙個大於1的數nu...
leetcode128 最長連續序列
給定乙個未排序的整數陣列,找出最長連續序列的長度。要求演算法的時間複雜度為 o n 示例 輸入 100,4,200,1,3,2 輸出 4 解釋 最長連續序列是 1,2,3,4 它的長度為 4。建立乙個dict,如果num不在裡面就檢視左右連續長度,再給num和左右處賦值 class solution...