總結演算法題中經常碰見給定陣列或者字串求其相關的最長「連續遞增」,「連續」等子串行或者子串。其主要是利用動態規劃演算法或者雜湊表等資料結構來解決問題。
子串與子串行區別:子串不可跳躍,子串行可以跳躍,如 「ace」是「abcde」的子串行,而不是子串。 而「abc」則是其子串。
最長連續遞增序列(lcis) : longest continuous increasing subsequenceleetcode 674最長上公升子串行(lis): longest increasing subsequence
最長連續序列(lcs): longest consecutive sequence
最長公共子串行(lcs): longest common subsequence
題目:給定乙個未經排序的整數陣列,找到最長且連續的的遞增序列,並返回該序列的長度。示例 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。輸入描寫敘述 輸入包括多組資料,每組資...