動態規劃演算法:每次決策依賴於當前狀態,又隨即引起狀態的轉移。乙個決策序列就是在變化的狀態中產生出來的,所以,這種多階段最優化決策解決問題的過程就稱為動態規劃。
在查詢有很多重疊子問題的情況的最優解有效。動態規劃儲存子問題的解,避免重複計算。
子序問題
解決動態規劃問題的關鍵是找到狀態轉移方程,這樣就可以通過計算和儲存子問題的解來解決最終問題。
給你乙個整數陣列 nums ,找到其中最長嚴格遞增子串行的長度。
子串行是由陣列派生而來的序列,刪除(或不刪除)陣列中的元素而不改變其餘元素的順序。例如,[3,6,2,7] 是陣列 [0,3,1,6,2,2,7] 的子串行。
示例 1:
輸入:nums =[10
,9,2
,5,3
,7,101,18
]輸出:4
解釋:最長遞增子串行是 [2,
3,7,
101],因此長度為 4 。
定義狀態轉移方程dp[i]表示i結尾的、最長子序列。對於每乙個位置i,如果之前存在某個位置j所對應的數字小於位置i所對應的數字,則我們可以獲得i結尾,長度為dp[j]+1的子串行
class
solution
: def lengthoflis
(self, nums: list[int])-
> int:
maxlength,n =0,
len(nums)
if n <=1:
return n
dp =[1
]*nfor i in
range
(n):
for j in
range
(i):
if nums[i]
> nums[j]
: dp[i]
=max
(dp[i]
, dp[j]+1
) maxlength =
max(maxlength,dp[i]
)return maxlength
該方法的時間複雜度為o(n^2),可以進行優化,採用二分法進行優化,將dp陣列中dp[k]儲存長度為k+1的最長遞增子串行的最後乙個數字。我們每遍歷乙個位置i,如果其對應數字大於dp陣列中所有數字值,那麼將其放在dp尾部,表示最長序列長度+1.如果發現dp陣列比數字a大,比數字b小,則將b更新為此數字,使得dp陣列永遠遞增。時間複雜度為o(nlogn)
class
solution
: def lengthoflis
(self, nums: list[int])-
> int:
n =len(nums)
if n <=1:
return n
dp =
dp.(nums[0]
)for i in
range(1
,n):
if dp[
len(dp)-1
]: dp.
(nums[i]
)else
:for j,k in
enumerate
(dp)
:if k >= nums[i]
:break
dp[j]
= nums[i]
return
len(dp)
給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。
乙個字串的 子串行 是指這樣乙個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。
例如,「ace」 是 「abcde」 的子串行,但 「aec」 不是 「abcde」 的子串行。兩個字串的「公共子串行」是這兩個字串所共同擁有的子串行。
若這兩個字串沒有公共子串行,則返回 0。
示例 1
:輸入:text1 =
"abcde"
, text2 =
"ace"
輸出:3
解釋:最長公共子串行是 "ace",它的長度為 3
建立二維陣列dp,其中dp[i][j[表示第乙個字串為位置i為止,到第二個字元位置j為止,最長的公共子串行長度
class
solution
: def longestcommonsubsequence
(self, text1: str, text2: str)
-> int:
m,n =
len(text1)
,len
(text2)
dp =[[
0]*(n+1)
for _ in
range
(m+1)]
for i in
range(1
,m+1):
for j in
range(1
,n+1):
if text1[i-1]
== text2[j-1]
: dp[i]
[j]= dp[i-1]
[j-1]+
1else
: dp[i]
[j]=
max(dp[i-1]
[j], dp[i]
[j-1])
return dp[m]
[n]
演算法學習 Union Find演算法
union find演算法有它的實際用途。多用於動態連通的應用場景。union find演算法是 給出兩個節點,判斷它們是否連通,如果連通,是不需要給出具體的路徑的 舉兩個例子作為主要表現 1 在網路連線中,當發現沒有連線的兩個節點,可以把他們連線起來,一旦節點都連線起來,又能把多餘的線拆除,這時候...
演算法學習 KM演算法
km演算法 用於求二分圖的最佳完美匹配 即權值最大的完美匹配 如果你也是個剛來學習km演算法的人 大概的用途肯定還是知道的吧 還是直接說重點吧 首先 理解km演算法前 必須有以下3個概念 1.可行頂標 對於乙個賦值二分圖g x,y,e,w x,y 代表二分圖的兩邊頂點標號 e代表邊 w代表邊的權值 ...
演算法 演算法學習01
貪婪 可以理解為最簡單基礎的求解方式,特點是 短視性 從這個特點入手很容易理解每一步取其最優的原理。雖然最終結果不一定是最好的,但是一定是較好的而且是最簡便的。因此在不過分追求最優結果或者對速度的要求高於結果的情況下,貪婪是不錯的選擇。分治可以理解為大事化小小事好搞,與貪婪的每一步的 串聯 不同,分...