給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。
示例:輸入:[10
,9,2
,5,3
,7,101,18
]輸出:
4 解釋: 最長的上公升子串行是 [2,
3,7,
101],它的長度是 4。
說明:可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。
你演算法的時間複雜度應該為 o
(n2) 。
高階: 你能將演算法的時間複雜度降低到 o
(n log n) 嗎?
此題與前兩篇部落格都屬於子串行問題,所以可以採用類似的動態規劃方法解決,這種方法的時間複雜度為o(n
2)
o(n^2)
o(n2
)。具體做法是假設dp[
i]
dp[i]
dp[i
]表示前i
ii個元素中的最長子序列長度,然後對於num
s[i]
nums[i]
nums[i
]需要比較他與前i−1
i-1i−
1個元素的大小,如果大於則則dp[
i]
dp[i]
dp[i
]應該更新。轉移方程為dp[
i]=m
ax(d
p[j]
)+
1dp[i]=max(dp[j])+1
dp[i]=
max(
dp[j
])+1
。**
class
solution}}
return
*max_element
(dp.
begin()
, dp.
end())
;}};
上述的動態規劃,似乎是這類題目的乙個通解,但是針對具體的題目也可以有一些優化,這一題題目要求優化到時間複雜度為o(n
logn
)o(nlogn)
o(nlog
n),看到這個複雜度要求的第一眼就想到了二分查詢的時間複雜度是log
nlogn
logn
,那麼也就是用了n
nn次二分查詢。但是二分查詢又是需要在乙個有序的序列中才能使用。
設當前已求出的最長上公升子串行的長度為 len
\textit
len初始時為 1),從前往後遍歷陣列 nums
\textit
nums
,在遍歷到 nums[i
]\textit[i]
nums[i
]時:如果 nums[i
]>d[
len]
\textit[i] > d[\textit]
nums[i
]>d[
len]
,則直接加入到 d 陣列末尾,並更新 len
=len+1
\textit = \textit +1
len=
len+1;
否則,在 d
dd 陣列中二分查詢,找到第乙個比 nums[i
]\textit[i]
nums[i
] 小的數 d[k
]d[k]
d[k]
,並更新 d[k
+1]=
nums[i
]d[k + 1] = \textit[i]
d[k+1]
=nums[i
]。以輸入序列 [0,
8,4,
12,2]
[0, 8, 4, 12, 2]
[0,8,4
,12,
2]為例:
第一步插入 0
00,d=[
0]
d = [0]
d=[0];
第二步插入 8
88,d=[
0,8]
d = [0, 8]
d=[0,8
];第三步插入 4
44,d=[
0,4]
d = [0, 4]
d=[0,4
];第四步插入 12
1212
,d =[
0,4,
12]
d = [0, 4, 12]
d=[0,4
,12]
;第五步插入 2
22,d=[
0,2,
12]
d = [0, 2, 12]
d=[0,2
,12]
。最終得到最大遞增子串行長度為 333。
**
class
solution
else r = mid -1;
} d[pos +1]
= nums[i];}
}return len;}}
;
300 最長上公升子串行
給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4 解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 高階 你能將演算法的時間複雜度降低到 o n log n 嗎?思路 遍歷一遍給定陣列,維護乙個陣列dp,dp i ...
300 最長上公升子串行
建立dp表,dp i 表示含第i個數字的最長上公升子串行的長度 求dp i 時,向前遍歷找出比i元素小的元素j,則動態方程為dp i max dp i dp j 1 class solution object def lengthoflis self,nums size len nums if si...
300 最長上公升子串行
給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10 9,2 5,3 7,101,18 輸出 4 解釋 最長的上公升子串行是 2,3,7,101 它的長度是 4。說明 可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。你演算法的時間複雜度應該為 o n2 高階 你能...