####最長有效括號
給定乙個只包含 『(』 和 『)』 的字串,找出最長的包含有效括號的子串的長度。dp表示0~i的有效括號子串的長度。示例 1:
輸入: 「(()」
輸出: 2
解釋: 最長有效括號子串為 「()」
示例 2:
輸入: 「)()())」
輸出: 4
解釋: 最長有效括號子串為 「()()」
遇到』(『直接跳過,因為之前沒有與之匹配的括號。
遇到』)』,我們則開始進行討論,j=i-1-dp[i-1] (我們需要跳過在這之前的已經匹配的有效子串) 例如: (()()) pos=6,j=1 dp[i-1]=4.
若j處的括號是』(』,那麼狀態轉移方程為:dp=dp]+2;
我們還需要加j-1之前的有效子串。例如: () (()())
class solution
int ans=0;
int len=s.length();
int dp=new int[len];
dp[0]=0;
for(int i=1;i=0&&s.charat(j)=='(')}}
ans=math.max(ans,dp[i]);
}return ans;
}}
#####最長上公升子串行
給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。
示例:輸入: [10,9,2,5,3,7,101,18]
輸出: 4
解釋: 最長的上公升子串行是 [2,3,7,101],它的長度是 4。
說明:可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。
你演算法的時間複雜度應該為 o(n2) 。
高階: 你能將演算法的時間複雜度降低到 o(n log n) 嗎?
o(logn)做法:利用lower_bound
class solution
int total=0;
int vec=new int[nums.length];
vec[total++]=nums[0];
for(int i=0;ivec[total-1])else
}return total;
}public int lower_bound(int arr,int k,int target)else
}return l;
}}
10. 正規表示式匹配給定乙個字串 (s) 和乙個字元模式 §。實現支援 『.』 和 『』 的正規表示式匹配。這道題我們需要分情況討論,首先先注意一點 * 前一定是有字母的,例如 a* 就表示a可以為0個也可以為n個。『.』 匹配任意單個字元。
'』 匹配零個或多個前面的元素。
匹配應該覆蓋整個字串 (s) ,而不是部分字串。
說明:s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母,以及字元 . 和 。
示例 1:
輸入:s = 「aa」
p = 「a」
輸出: false
解釋: 「a」 無法匹配 「aa」 整個字串。
示例 2:
輸入:s = 「aa」
p = "a"
輸出: true
解釋: 『』 代表可匹配零個或多個前面的元素, 即可以匹配 『a』 。因此, 重複 『a』 一次, 字串可變為 「aa」。
示例 3:
輸入:s = 「ab」
p = "."
輸出: true
解釋: "." 表示可匹配零個或多個(』』)任意字元(』.』)。
示例 4:
輸入:s = 「aab」
p = 「cab」
輸出: true
解釋: 『c』 可以不被重複, 『a』 可以被重複一次。因此可以匹配字串 「aab」。
示例 5:
輸入:s = 「mississippi」
p = 「misisp*.」
輸出: false
我們就要分清理討論了。
首先dp表示s串前i個與p串前j個字元的匹配情況。
如果si == pj的話,dp=dp
如果pj == '.'的話,dp=dp,同上。
接下來就要討論pj == '*'的情況了。
至於初始化,dp[0][0]表示我們兩個串還沒開始匹配,那麼肯定為true
class solution
int n=s.length();
int m=p.length();
boolean dp=new boolean[n+1][m+1];
dp[0][0]=true;
for(int i=1;i44. 萬用字元匹配
給定乙個字串 (s) 和乙個字元模式 § ,實現乙個支援 『?』 和 『』 的萬用字元匹配。
『?』 可以匹配任何單個字元。
'』 可以匹配任意字串(包括空字串)。
兩個字串完全匹配才算匹配成功。
說明:s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母,以及字元 ? 和 。
示例 1:
輸入:s = 「aa」
p = 「a」
輸出: false
解釋: 「a」 無法匹配 「aa」 整個字串。
示例 2:
輸入:s = 「aa」
p = ""
輸出: true
解釋: 『』 可以匹配任意字串。
示例 3:
輸入:s = 「cb」
p = 「?a」
輸出: false
解釋: 『?』 可以匹配 『c』, 但第二個 『a』 無法匹配 『b』。
示例 4:
輸入:s = 「adceb」
p = 「ab」
輸出: true
解釋: 第乙個 '』 可以匹配空字串, 第二個 '』 可以匹配字串 「dce」.
示例 5:
輸入:s = 「acdcb」
p = "ac?b"
輸入: false
這道題比上一道更加直觀,討論的情況也少很多。
首先dp表示s串前i個與p串前j個字元的匹配情況。
如果si==pj的話,dp=dp
如果pj=='.'的話,dp=dp,同上。
接下來就要討論pj=='*'的情況了。這一步是和上面一樣的。
當pj=='*'的時候,其實很直觀,*只有為空串或者匹配n個字元,而且多個字元是從s串第i個到第i+n-1個這個範圍,
不可能是這個範圍之外的串了,自己推一下就知道了。
匹配多個字元,就和上一題一樣,dp=dp,就是s串刪除乙個字元,只是上一題刪除的重複的字元,
這一題刪除的是不重複的多個字元。
接著是空串,即dp=dp,即把*刪掉,還有就是匹配乙個字元,也是dp=dp.
那麼轉移方程就是dp=dp||dp.其中一種成立即為true.
記得初始化化,即dp[0][0]不一定是開始的點,例如: ???? ?是可以為空串的。可以從dp[0][1]開始,
也可以從dp[0][2]開始,以此類推。
class solution
int n=s.length();
int m=p.length();
boolean dp=new boolean[n+1][m+1];
dp[0][0]=true;
for(int i=1;i<=m;++i)
}for(int i=1;i<=n;++i)
if(p.charat(j-1)=='*')}}
return dp[n][m];
}}
石子合併 —區間dp
傳送門
動態規劃合集
看999,999比 1大,但dp 7 dp 5 1的,即999要和前面的1234組成最長序列,不能和 1組成最長,所以不僅要前面挑後面 a j dp i 999是合格的 後面 但 1 2是不合格的 前面 static void solve dpv i push back a i int k 1 fo...
動態規劃 常見揹包問題合集
01揹包 有n件物品和乙個容量為v的揹包。每件物品只有一件 第i件物品的費用是c i 價值是v i 求解將哪些物品裝入揹包使總價值最大。轉移方程 f i v max,可以優化只用一維陣列.如下 for int i 0 i w i j if record j c i v i record j reco...
動態規劃 什麼是動態規劃?
先來看看 資訊學奧賽一本通第5版 是怎麼說的 動態規劃程式設計是對解最優化問題的一種途徑 一種方法,而不是一種特殊演算法。不像前面所述的那些搜尋或數值計算那樣,具有乙個標準的數學表示式和明確清晰的解題方法。動態規劃程式設計往往是針對一種最優化問題,由於各種問題的性質不同,確定最優解的條件也互不相同,...