嚴格遞增和非嚴格遞增最長遞增子串行長度

2021-09-26 15:42:27 字數 3497 閱讀 5642

最長遞增子串行,給定乙個無序整數陣列nums(字串也可以,不重要),給出最長嚴格遞增子串行的長度。比如輸入[1, 2 , 1, -1, 1, 4, 0],輸出3,最長遞增子串行[1, 2, 4],當然可能不唯一,[-1, 1, 4]也是乙個,但是並不影響長度。

強行遍歷就不說了,時間複雜度o(2^n),簡直**。

思路1:動態規劃,建立乙個陣列dp,dp[i]記錄nums[0:i]的最長遞增子串行的長度。

d p[

i]=m

ax(d

p[j]

+1),

j∈

dp[i] = max(dp[j]+1),j∈\

dp[i]=

max(

dp[j

]+1)

,j∈輸出max(dp)即可,時間複雜度o(n^2),空間複雜度o(n)。

public int maxlengthcsub

(int[

] nums)

int len = nums.length;

if(len ==

0|| len ==1)

int maxlen =1;

int[

] dp =

newint

[len]

;for

(int i =

0; i < len; i++)}

}return maxlen;

}

思路2:動態規劃+二分查詢

同樣建立乙個陣列dp,但是這裡dp記錄的是上公升子串行,遍歷nums室,用nums的元素填充dp,填充規則是什麼呢?首先利用二分查詢找到nums[i]在dp中應該插入的位置j,若j==當前dp的長度,則在dp末尾插入nums[i],maxlen加一,否則dp[j]=nums[i]。這裡可能有個疑問,比如說nums[i0]=1放入dp[1],在後面的遍歷中有乙個nums[i1]=-1也需要放入dp[1],此時不會影響長度的計算嗎?答案是不會,用乙個例子比較容易理解。

input:[1

,2,1

,-1,

1,4,

0]dp:[1]

, maxlen =

1dp:[1

,2], maxlen =

2dp:[1

,2], maxlen =

2dp:[-

1,2]

, maxlen =

2dp:[-

1,1]

, maxlen =

2dp:[-

1,1,

4], maxlen =

3dp:[-

1,0,

4], maxlen =

3

這裡[-1, 0, 4]雖然不是乙個最長遞增子串行,但是並不會影響maxlen的值。

時間複雜度o(nlgn),空間複雜度o(n)。

public int maxlengthcsub

(int[

] nums)

if(nums.length ==

0|| nums.length ==1)

int[

] dp =

newint

[nums.length]

; int maxlen =0;

for(int i =

0; i < nums.length; i++

)return maxlen;

}// 二分查詢,找到target在nums[0:len-1]的插入位置

public int findindex

(int[

] nums, int len, int target)

return low;

}

思路1:同嚴格遞增的思路1,只需要在比較的時候加個等號:

d p[

i]=m

ax(d

p[j]

+1),

j∈

dp[i] = max(dp[j]+1),j∈\

dp[i]=

max(

dp[j

]+1)

,j∈思路2:基本類似嚴格遞增的思路1,但是這裡插入的規則是要變的,不再是用二分查詢插入dp,其插入位置要保證

d p[

i−1]

<=d

p[i]

[i+1

]dp[i-1] <= dp[i] < dp[i+1]

dp[i−1

]<=d

p[i]

[i+1

]邊界情況這裡就不分析了,程式裡也不需要進行分析,只需要求出i即可,同樣求出i==maxlen,maxlen加一。還是通過乙個例子來看。

input:[1

,2,1

,-1,

1,4,

0]dp:[1]

, maxlen =

1dp:[1

,2], maxlen =

2dp:[1

,1], maxlen =

2dp:[-

1,1]

, maxlen =

2dp:[-

1,1,

1], maxlen =

3dp:[-

1,1,

1,4]

, maxlen =

4dp:[-

1,0,

1,4]

, maxlen =

4

看出不一樣來了吧,主要是1的插入位置,不在是替換掉前面的1,而是在前面的1的後面放入新的1。

public int maxlengthcsub

(int[

] nums)

int len = nums.length;

if(len ==

0|| len ==1)

int[

] dp =

newint

[len]

; int maxlen =0;

for(int i =

0; i < len; i++

)return maxlen;

}// 同嚴格遞增

// 二分查詢,找到target在nums[0:len-1]的插入位置

public int findindex

(int[

] nums, int len, int target)

return low;

}// 返回-1時,正常使用二分查詢即可

public int findrindex

(int[

] nums, int low, int tar)

int high = low +1;

while

(high < nums.length && nums[high]

== nums[low]

)return high;

}

最長遞增子串行

這是微軟實習生筆試遇到的,題意 求乙個陣列中最長遞增子串行的長度。要求選擇該題最好演算法的時間複雜度和空間複雜度。答案 時間複雜度o nlgn 空間複雜度o n 這題明顯用動態規劃來解。假設在目標陣列array 的前i個元素中,以array i 元素為最大元素的遞增子串行的長度是lis i 那麼 遞...

最長遞增子串行

最長遞增子串行又叫做最長上公升子串行 子串行,正如lcs一樣,元素不一定要求連續。本節討論實現三種常見方法,主要是練手。題 求乙個一維陣列arr i 中的最長遞增子串行的長度,如在序列1,1,2,3,4,5,6,7中,最長遞增子串行長度為4,可以是1,2,4,6,也可以是 1,2,4,6。方法一 d...

最長遞增子串行

最長遞增子串行 求乙個字串的最長遞增子串行 如 dabdbf最長遞增子串行就是abdf,長度為4 這是一道基本的動態規劃求解的題目,與此類似的還有 最長公共子串行 分析 用一維陣列dp i 來儲存以a i 為末元素的最長遞增子串行的長度,那麼dp i 至少為1 即包含它本身 往前尋找,如果存在a j...