給定乙個未排序的整數陣列,找出最長連續序列的長度。
說明
要求你的演算法複雜度為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 其最長上公...