LintCode刷題 124 最長連續序列

2021-09-11 13:16:18 字數 3575 閱讀 5220

給定乙個未排序的整數陣列,找出最長連續序列的長度。

說明

要求你的演算法複雜度為o(n)

樣例

給出陣列[100, 4, 200, 1, 3, 2],這個最長的連續序列是 [1, 2, 3, 4],返回所求長度 4

從乙個陣列整數陣列中找最長的連續序列。首先,連續序列的意思是[1,2,3,4,7],其中,[1,2,3,4]就是連續序列。最長的連續序列的意思,乙個陣列中可能會有多個連續序列,題目要求的就是最長的那個,而且只需要返回其長度。

題目中給出的未排序的整數陣列。那我們的第乙個思路,肯定是先排序,然後再求解。排序後就很簡單了。但是題目要求複雜度為o(n),所以就不能使用排序了,因為排序最快的複雜度是o(nlogn)。

思路一有個比較簡單的想法,我們先拿到陣列中的乙個元素i,然後從陣列中遍歷查詢到i-1,i-2...如果找不到,證明連續序列斷了,記錄下前面的長度為leftlength。接著遍歷查詢到i+1,i+2...記錄下其長度rightlength。那麼,在整個陣列中,與i相連的那個連續序列就找到了。而且序列的長度length=leftlength+rightlength+1.接著再從陣列中拿到元素j,遍歷查詢到j-1,j-2...然後遍歷查詢到j+1,j+2...以此類推,就能找到所有的連續序列。 但是這裡有兩個問題需要解決:

從陣列中查詢特定元素i-1,其複雜度為o(n),顯然複雜度不符合要求。我們想要的是直接o(1)複雜度就能查詢到i-1。沒錯,字典就能實現。將陣列的所有元素作為字典的key,那麼在字典中查詢i-1這個key,就代表陣列裡面有i-1這個元素。

去了i之後,接著查詢i-1,i-2...由於這些元素是連續序列,所以操作過後需要把他們刪除掉。刪除掉是不會有影響的。但是不刪除,就會有很多無用的重複操作。比如i的時候,查詢到i-1,那些下次拿到i-1,又查詢到了同乙個連續序列,沒有意義,而且複雜度也高。

基於以上思路,由於字典中的每個元素都只遍歷了一次,所以時間複雜度為o(n),用到了乙個字典儲存所有的元素,所以控制項複雜度也為n。

思路二跟思路一相同,使用字典來儲存陣列中的元素,以陣列中的元素為key,但是value是已經查詢到的與元素有關的連續序列的長度。 我從陣列中拿到值為i的元素,接著我查詢key為i-1和i+1的元素,如果存在,則記其value分別為leftlength和rightlength。這時,設key為i的元素的value值length=leftlength+rightlength+1.新增到字典裡面去。同時,將i-leftlength和i+rightlength的元素(也就是已知的跟i有關的連續序列的兩端的元素,實際上你可以更新所有跟i有關的元素的值,但是這樣做沒有意義,中間的元素以後再也用不到了)的value也設為length。當所有的元素都遍歷完了,就能查詢到最大的連續序列長度了。

文字說明有點難理解,用幾個簡單的元素說明下。

陣列[1,3,2,7,4] 字典初始化為空{}

第一次遍歷拿到1(沒查詢到值):結果

第二次遍歷拿到3(沒查詢到值):結果

第三次遍歷拿到2(查詢到1和3):結果

第四次遍歷拿到7(沒查詢到值):結果

第五次遍歷拿到4(查詢到3):結果(注意這裡更新的是1:4)

思路一**

""

" @param num: a list of integers

@return: an integer

""" def longestconsecutive(self, num):

#最大的連續序列長度

maxlength = 0

#字典,key為num的元素,value都是true

numdict = {}

for i in num:

numdict[i] = true

for i in num:

if not numdict.has_key(i):

continue

leftlength = 0

rightlength = 0

left = i-1

right = i+1

#往左遍歷,直到left-1不存在

while numdict.has_key(left):

#找到了就刪除元素,避免重複查詢

del numdict[left]

leftlength += 1

left -= 1

#往右遍歷,直到right+1不存在

while numdict.has_key(right):

#找到了就刪除元素,避免重複查詢

del numdict[right]

rightlength += 1

right += 1

#刪除當前元素,避免重複查詢

del numdict[i]

#計算與i相連的連續序列的長度

length = leftlength + rightlength + 1

maxlength = max(maxlength,length)

return maxlength

複製**

思路二**
""

" @param num: a list of integers

@return: an integer

""" def longestconsecutive1(self, num):

# write your code here

#字典,key是num中的元素,value是當前算出來的與該數相連的連續序列的長度

numdict = {}

#最大的連續序列長度

maxlength = 0

for i in num:

#如果之前已經操作過i,則不再操作

if numdict.has_key(i):

continue

left = 0

right = 0

leftkey = i-1

rightkey = i+1

#能在字典中找到i-1這個key,拿到left的值

if numdict.has_key(leftkey):

left = numdict[leftkey]

#能在字典中找到i+1這個key,拿到right的值

if numdict.has_key(rightkey):

right = numdict[rightkey]

#與i相連的連續序列的長度

length = left + right + 1

print

"i= %d left= %d right=%d length= %d"%(i,left,right,length)

#存到字典

numdict[i] = length

#更新與i相連的連續序列的最左邊和最右邊的長度值

numdict[i-left] = length

numdict[i+right] = length

maxlength = max(maxlength,length)

return maxlength

複製**

個人目前只懂一丁點python語法,所以不做語法上的優化,而且整體**風格效果會盡量跟c語言趨於一致。

lintcode 124 最長連續序列

給定乙個未排序的整數陣列,找出最長連續序列的長度。說明要求你的演算法複雜度為o n 樣例給出陣列 100,4,200,1,3,2 這個最長的連續序列是 1,2,3,4 返回所求長度 4 標籤陣列 思路 由於限定了時間複雜度為 o n 所以採取先排序再遍歷的方式是不適合的,於是以空間換時間,用 set...

LintCode刷題隨筆

給出乙個陣列nums包含n 1個整數,每個整數是從1到n 包括邊界 保證至少存在乙個重複的整數。假設只有乙個重複的整數,找出這個重複的數。1.不能修改陣列 假設陣列只能讀 2.只能用額外的o 1 的空間 3.時間複雜度小於o n 2 4.陣列中只有乙個重複的數,但可能重複超過一次 您在真實的面試中是...

LintCode刷題 最長上公升連續子串行

問題描述 給定乙個整數陣列 下標從 0 到 n 1,n 表示整個陣列的規模 請找出該陣列中的最長上公升連續子串行。最長上公升連續子串行可以定義為從右到左或從左到右的序列。樣例 給定 5,4,2,1,3 其最長上公升連續子串行 lics 為 5,4,2,1 返回4.給定 5,1,2,3,4 其最長上公...