1、第一種思路模板是乙個一維的 dp 陣列:
int n = array.length;
int[
] dp =
newint
[n];
for(
int i =
1; i < n; i++
)}
例如「最長遞增子串行」,在這個思路中 dp 陣列的定義是:
在子陣列 array[0…i] 中,我們要求的子串行(最長遞增子串行)的長度是 dp[i]。
2、第二種思路模板是乙個二維的 dp 陣列:
int n = arr.length;
int[
] dp =
new dp[n]
[n];
for(
int i =
0; i < n; i++
)}
這種思路運用相對更多一些,尤其是涉及兩個字串/陣列的子串行,比如「最長公共子串行」。本思路中 dp 陣列含義又分為「只涉及乙個字串」和「涉及兩個字串」兩種情況。
2.1 涉及兩個字串/陣列時(比如最長公共子串行),dp 陣列的含義如下:
在子陣列 arr1[0…i] 和子陣列 arr2[0…j] 中,我們要求的子串行(最長公共子串行)長度為 dp[i][j]。
在子陣列 array[i…j] 中,我們要求的子串行(最長回文子串行)的長度為 dp[i][j]。
給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。
示例:輸入: [10,9,2,5,3,7,101,18]
輸出: 4
解釋: 最長的上公升子串行是 [2,3,7,101],它的長度是 4。
說明:可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。
你演算法的時間複雜度應該為 o(n2) 。
高階: 你能將演算法的時間複雜度降低到 o(n log n) 嗎?
//動態規劃
class
solution}}
int max=0;
for(
int i=
0;isize()
;i++)}
return max;}}
;
時間複雜度:o(n^2),這裡 n 是陣列的長度,我們寫了兩個 for 迴圈,每個 for 迴圈的時間複雜度都是線性的。
空間複雜度:o(n),要使用和輸入陣列長度相等的狀態陣列,因此空間複雜度是 o(n)。
鏈結給定乙個未排序的整數陣列,找到最長遞增子串行的個數。
示例 1:
輸入: [1,3,5,4,7]
輸出: 2
解釋: 有兩個最長遞增子串行,分別是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
示例 2:
輸入: [2,2,2,2,2]
輸出: 5
解釋: 最長遞增子串行的長度是1,並且存在5個子序列的長度為1,因此輸出5。
注意: 給定的陣列長度不超過 2000 並且結果一定是32位有符號整數。
class
solution
else
if(nums[i]
>nums[j]
&&count[i]
==count[j]+1
)}}int loc_max=
0,ret=0;
for(
int i=
0;isize()
;i++)}
for(
int i=
0;isize()
;i++)}
//return num_count[loc_max];//錯誤
return ret;}}
;
給定乙個字串 s ,找到其中最長的回文子串行,並返回該序列的長度。可以假設 s 的最大長度為 1000 。
示例 1:
輸入:"bbbab"
輸出:4
乙個可能的最長回文子串行為 "bbbb"。
示例 2:
輸入:"cbbd"
輸出:2
乙個可能的最長回文子串行為 "bb"。
- 1 <= s.length <= 1000
- s 只包含小寫英文本母
//為了保證每次計算 dp[i][j],左下右方向的位置已經被計算出來,只能斜著遍歷或者反著遍歷:
//反著遍歷保證正確的狀態轉移
for(
int i=n-
1;i>=
0;i--
)else}}
return dp[0]
[n-1];}};
給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。
乙個字串的 子串行 是指這樣乙個新的字串:它是由原字串在不改變字元的相對順序的情況下刪除某些字元(也可以不刪除任何字元)後組成的新字串。
例如,「ace」 是 「abcde」 的子串行,但 「aec」 不是 「abcde」 的子串行。兩個字串的「公共子串行」是這兩個字串所共同擁有的子串行。
若這兩個字串沒有公共子串行,則返回 0。
示例 1:
輸入:text1 = "abcde", text2 = "ace"
輸出:3
解釋:最長公共子串行是 "ace",它的長度為 3。
示例 2:
輸入:text1 = "abc", text2 = "abc"
輸出:3
解釋:最長公共子串行是 "abc",它的長度為 3。
示例 3:
輸入:text1 = "abc", text2 = "def"
輸出:0
解釋:兩個字串沒有公共子串行,返回 0。
1 <= text1.length <= 1000
1 <= text2.length <= 1000
輸入的字串只含有小寫英文本元。
class
solution
else}}
return dp[m]
[n];}}
;
給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: 「babad」
輸出: 「bab」
注意: 「aba」 也是乙個有效答案。
示例 2:
輸入: 「cbbd」
輸出: 「bb」
//法一:動態規劃法
class
solution
else
if(l==1)
else
if(dp[i]
[j]&&l+
1>ans.
size()
)}}return ans;}}
;//法二:中心擴充套件演算法
/*列舉所有的「回文中心」並嘗試「擴充套件」,直到無法擴充套件為止,此時的回文串長度即為此「回文中心」下的最長回文串長度。*/
class
solution
return;}
string longestpalindrome
(string s)
if(right2 - left2 > end - start)
}return s.
substr
(start, end - start +1)
;}};
子串行 子串
def foo num list 求陣列中最大子串行的和,子串行必須連續 length len num list max value 10000000000 tmp 0 for i in range length tmp max tmp num list i num list i max value...
最長回文子串 回文子串行 公共子串行
一 最長回文子串 連續 1.manacher演算法 見前面 2.動態規劃 bool p 100 100 for int i 0 i 2 reutrn s.substr start,maxlength 二 最長回文子串行 不連續 1.遞迴 2.動態規劃 3.將字串反轉,再求兩個字串的最長公共子串行lc...
兩子串的公共子串行
兩子串的公共子串行,子串行的問題難比子串,暴力也難搞,動態規劃 好,1.確定dp i j dp i j 表示字串str1的 0,i 和str2的 0,j 的最大公共子串行 2.填已經確定的dp值,這裡是第一行str1的 0,n1 和str2的 0 的最大公共子串行,第一列str1的 0 和str2的...