最長遞增子串行,給定乙個無序整數陣列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...