尋找陣列中最大遞增子串行

2021-08-20 08:09:01 字數 2830 閱讀 8619

參考部落格:尋找陣列中最大遞增子串行

#coding=utf-8

# 尋找list中的最長遞增子串行.. 不要求元素必須彼此相鄰.. 如:[1,-1,2,-3,4,-5,6,-7] >> [1,2,4,6]

# # 這段**我真是看了很久都還沒完全吃透理解...

def getdp(arr):

n = len(arr)

# dp儲存到當前位置i為止的,最長遞增子串行長度..

# end儲存當前最大遞增子串行最大元素,的最小值 maxv

dp, ends = [0] * n, [0] * n

ends[0], dp[0] = arr[0], 1

right = 0

for i in range(1, n):

l = 0

r = right # end[0,...right]

# 二分查詢,找到當前的s[i]是否是可以比前i-1個中的某個值大.

# 若找不到,則更新ends[l或r]

# 若arr[i]比ends有效區的值都大,則l=right+1

# s = [2, 1, 5, 3, 6, 4, 8, 9, 7]

while l <= r:

m = (l + r) / 2 # 二分查詢使更快..

if arr[i] > ends[m]: # 這是沒找到end大於a[i]的情況,則繼續二分查詢..

l = m + 1

else:

r = m - 1

# while迴圈是直到l>r才退出的..

right = max(right, l)

ends[l] = arr[i] #

dp[i] = l + 1

return dp

def generatelis(arr, dp):

n = max(dp)

index = dp.index(n)

lis = [0] * n

n -= 1

lis[n] = arr[index]

# 從右向左

for i in range(index, 0 - 1, -1):

# 關鍵

if arr[i] < arr[index] and dp[i] == dp[index] - 1:

n -= 1

lis[n] = arr[i]

index = i

return lis

s = [2, 1, 5, 3, -1, 4, 3, -3, -2]

dp = getdp(s)

print '方法一##############', max(dp)

res = generatelis(s, dp)

print res

######################### my code1 #############################

# 時間複雜度o(n^2)..

# 效率最低的...

def fun(s):

n = len(s)

lis = [1] * n

for i in range(n):

for j in range(i): # j,遍歷當前的最大遞增子串行

if s[i] > s[j] and lis[j] + 1 > lis[i]:

lis[i] = lis[j] + 1

return max(lis)

s = [2, 1, 5, 3, -1, 4, 3, -3, -2]

res1 = fun(s)

print '方法二#############', res1

######################### my code2 #############################

def fun2(s):

n = len(s)

lis = [1] * n # 存放每個i位置的最長子序列值

maxv = [1] * (n + 1) # 存放最長子序列內的最大值

maxv[1] = 1

maxv[0] = min(s) - 1 # 取邊界?

maxlen = 1 # 最大的遞增子串行長度

for i in range(1, n):

# j是遍歷當前最大的遞增子串行長度

for j in range(maxlen, -1, -1): # 這裡需要逆序注意!!!

if s[i] > maxv[j]: # 找到了現在進來的這個s[i]比哪乙個長度的j對應的maxv值大,那麼lis[i]就是j+1

lis[i] = j + 1

break # 找打了就可以馬上break了,不需要再遍歷更前面的maxv值..

if lis[i] > maxlen:

maxlen = lis[i]

maxv[lis[i]] = s[i]

# 這個else是因為s[i]進來沒能lis[i]大於maxlen,即可能s[i]找到的大於的maxv[j]j是比較靠中間的j,所以它是存在maxv[j + 1]的

# 所以如果maxv[j + 1]更大s[i]更小,那麼s[i]可以替換掉maxv[j + 1]

elif maxv[j] < s[i] and s[i] < maxv[j + 1]:

maxv[j + 1] = s[i]

return maxlen

s = [2, 1, 5, 3, -1, 4, 3, -3, -2]

res2 = fun2(s)

print '方法三###############'

方法以一直還是沒吃透。。。

放上來希望有大神能願意指點一二。。。~~

陣列中最長遞增子串行

陣列是亂序的,如1,1,2,3,4,5,6,7 根據無後效性定義,陣列中當前元素所形成的子串行與其前面元素形成的子串行沒有關係,所以 lis i 1 max 1,lis k 1 其中,array i 1 arry k 且任意k i lis i 儲存對於當前陣列arry i 形成的最長子序列的長度值,...

求陣列中最長遞增子串行

原文見 分析過程很清楚。這裡主要是 部分有改動。完全用c寫的,從檔案中讀入。另外,解法二的程式加了去重,求的是最長單調遞增子串行。求陣列中最長遞增子串行 寫乙個時間複雜度盡可能低的程式,求乙個一維陣列 n個元素 中的最長遞增子串行的長度。例如 在序列1,1,2,3,4,5,6,7中,其最長的遞增子串...

求陣列中最長遞增子串行

最長遞增子串行,longest increasing subsequence 下面我們簡記為 lis。排序 lcs演算法 以及 dp演算法就忽略了,這兩個太容易理解了。假設存在乙個序列d 1.9 2 1 5 3 6 4 8 9 7,可以看出來它的lis長度為5。下面一步一步試著找出它。我們定義乙個序...