最長子序列和子串相關演算法題總結

2021-10-09 14:49:17 字數 4267 閱讀 8907

總結演算法題中經常碰見給定陣列或者字串求其相關的最長「連續遞增」,「連續」等子串行或者子串。其主要是利用動態規劃演算法或者雜湊表等資料結構來解決問題。

子串與子串行區別:子串不可跳躍,子串行可以跳躍,如 「ace」是「abcde」的子串行,而不是子串。 而「abc」則是其子串。

最長連續遞增序列(lcis) : longest continuous increasing subsequence

最長上公升子串行(lis): longest increasing subsequence

最長連續序列(lcs): longest consecutive sequence

最長公共子串行(lcs): longest common subsequence

leetcode 674

題目:給定乙個未經排序的整數陣列,找到最長且連續的的遞增序列,並返回該序列的長度。

示例 1:

輸入: [1,3,5,4,7]

輸出: 3

解釋: 最長連續遞增序列是 [1,3,5], 長度為3。

儘管 [1,3,5,7] 也是公升序的子串行, 但它不是連續的,因為5和7在原陣列裡被4隔開。

示例 2:

輸入: [2,2,2,2,2]

輸出: 1

解釋: 最長連續遞增序列是 [2], 長度為1。

注意:陣列長度不會超過10000。

/*

* 1* leetcode 674 : 最長連續遞增序列

* */int

findlengthoflcis

(vector<

int>

& nums)

}return

max(res, cur);}

/*int findlengthoflcis(vector& nums)

}return res;

}*/

leetcode 673

題目:給定乙個未排序的整數陣列,找到最長遞增子串行的個數。

示例 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位有符號整數。

/*

* 2* leetcode 673 : 最長遞增子串行的個數

* */int

findnumberoflis

(vector<

int>

& nums));

int mx =1;

for(

int i =

1; i < n;

++i);}

else

if(dp[i]

.first == dp[j]

.first +1)

}}mx =

max(mx, dp[i]

.first);}

int res =0;

for(

int i =

0; i < n;

++i)

}return res;

}

leetcode 300

題目:給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。

示例:輸入: [10,9,2,5,3,7,101,18]

輸出: 4

解釋: 最長的上公升子串行是 [2,3,7,101],它的長度是 4。

說明:可能會有多種最長上公升子串行的組合,你只需要輸出對應的長度即可。

你演算法的時間複雜度應該為 o(n2) 。

高階: 你能將演算法的時間複雜度降低到 o(n log n) 嗎?

/*

* 3* leetcode 300 : 最長上公升子串行

* *//*

dp[i] 為考慮前 i 個元素,以第 i 個數字結尾的最長上公升子串行的長度,注意 nums[i] 必須被選取。

狀態轉移方程為:

dp[i]=max(dp[j])+1, 其中 0≤jint

lengthoflis

(vector<

int>

& nums)}}

return res;

}

leetcode 128

題目:給定乙個未排序的整數陣列,找出最長連續序列的長度。

要求演算法的時間複雜度為 o(n)。

示例:輸入: [100, 4, 200, 1, 3, 2]

輸出: 4

解釋: 最長連續序列是 [1, 2, 3, 4]。它的長度為 4。

/*

* 4* leetcode 128 : 最長連續序列

* *//*

1. 我們考慮列舉陣列中的每個數 x,考慮以其為起點,不斷嘗試匹配 x+1,x+2,⋯ 是否存在,假設最長匹配到了

x+y,那麼以 x 為起點的最長連續序列即為 x,x+1,x+2,⋯,x+y,其長度為 y+1,我們不斷列舉並更新答案即可。

2. 如果已知有乙個 x,x+1,x+2,⋯,x+y 的連續序列,而我們卻重新從 x+1,x+2 或者是 x+y 處開始嘗試匹配,

那麼得到的結果肯定不會優於列舉 x 為起點的答案,因此我們在外層迴圈的時候碰到這種情況跳過即可。

3. 由於我們要列舉的數 x 一定是在陣列中不存在前驅數 x−1 的,不然按照上面的分析我們會從 x−1 開始嘗試匹配,

因此我們每次在雜湊表中檢查是否存在 x−1 即能判斷是否需要跳過了。

4. 外層迴圈需要 o(n) 的時間複雜度,只有當乙個數是連續序列的第乙個數的情況下才會進入內層迴圈,

然後在內層迴圈中匹配連續序列中的數,因此陣列中的每個數隻會進入內層迴圈一次。根據上述分析可知,總時間複雜度為 o(n)。

*/int

longestconsecutive

(vector<

int>

& nums)

return res;

}

leetcode 1143

/*

* 5* leetcode 1143 : 最長公共子串行

* */// method 1

#if 0

自底向上 動態規劃

dp[i]

[j]表示的是s1[0..

.i−1

]與s2[0..

.j−1

]的最長公共子串行的長度,要求的是dp[m−1

][n−1

]動態轉移方程:

dp[i]

[j]=

#endif

intlongestcommonsubsequence

(string text1, string text2)

vectorint>

>

dp(text1.

size()

+1, vector<

int>

(text2.

size()

+1,0

));for

(int i =

0; i < text1.

size()

; i++)}

return dp[text1.

size()

][text2.

size()

];}// method 2

#if 0

// 自頂向下 遞迴 + 記憶化搜尋

intrecursion

(string& text1, string& text2,

int m,

int n, vectorint>

>

& memo)

intlongestcommonsubsequence

(string text1, string text2)

#endif

以上是最長子序列和子串相關演算法題彙總,個別題目也給出了解題思路和注釋,以及多種解法。

所有**都可以去我的github**檢視,後續也將繼續補充其他演算法方面的相關題目。

求最長子序列和最長公共子串

又有一段時間沒刷題,今天溫故下,最長公共子串行和最長公共子串概念不一樣,子串行可以不連續,子串必須連續,這兩題均可以用動態規劃解決!下面程式在vs上跑過無問題!include include include includeusing namespace std 動態規劃求最長子序列 int long...

演算法題 最長上公升子串行

題目描述 廣場上站著一支隊伍,她們是來自全國各地的扭秧歌代表隊,現在有她們的身高資料,請你幫忙找出身高依次遞增的子串行。例如隊伍的身高資料是 1 7 3 5 9 4 8 其中依次遞增的子串行有 1 7 1 3 5 9 1 3 4 8 等,其中最長的長度為4。輸入描述 輸入包含多組資料,每組資料第一行...

演算法題 最長上公升子串行

題目描寫敘述 廣場上站著一支隊伍。她們是來自全國各地的扭秧歌代表隊。如今有她們的身高資料。請你幫忙找出身高依次遞增的子串行。比如隊伍的身高資料是 1 7 3 5 9 4 8 當中依次遞增的子串行有 1 7 1 3 5 9 1 3 4 8 等,當中最長的長度為4。輸入描寫敘述 輸入包括多組資料,每組資...