日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最长重复子数组最长公共子序列不相交的线

發(fā)布時(shí)間:2025/3/21 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最长重复子数组最长公共子序列不相交的线 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

引言

這同樣是兩種類型的題目,有很多相似的地方和不同的地方,區(qū)別依然是連續(xù)和不連續(xù)之分。

最長重復(fù)子數(shù)組

給兩個(gè)整數(shù)數(shù)組 A 和 B ,返回兩個(gè)數(shù)組中公共的、長度最長的子數(shù)組的長度。

示例:
輸入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
輸出:3
解釋:
長度最長的公共子數(shù)組是 [3, 2, 1] 。

提示:

1 <= len(A), len(B) <= 1000
0 <= A[i], B[i] < 100

這道題中說的子數(shù)組,其實(shí)就是連續(xù)的子序列,
1,dp[i][j] 表示以下標(biāo)i - 1為結(jié)尾的A,和以下標(biāo)j - 1為結(jié)尾的B,最長重復(fù)子數(shù)組長度為dp[i][j]。
2,因?yàn)閐p[i][j]是由dp[i - 1][j - 1]推導(dǎo)出來的。所以當(dāng)A[i - 1] 和B[j - 1](對應(yīng)的是dp[i][j],dp[i - 1][j - 1]對應(yīng)的是A[i - 2] 和B[j - 2])相等的時(shí)候,dp[i][j] = dp[i - 1][j - 1] + 1;
3,dp[i][0] 和dp[0][j]初始化為0,因?yàn)楫?dāng)一個(gè)字符數(shù)組不存在時(shí)肯定沒有公共長度,且在這里其實(shí)也是沒有意義的,因?yàn)锳,B長度規(guī)定大于等于1,所以不會為0,但是為了轉(zhuǎn)移方程的計(jì)算,所以還是需要進(jìn)行初始化;
4,循環(huán)肯定是從前往后的,A,B二重循環(huán)誰在里面誰在都一樣;

代碼如下:

class Solution { public:int findLength(vector<int>& nums1, vector<int>& nums2) {int len1 = nums1.size(), len2 = nums2.size();vector<vector<int>> dp(len1 + 1, vector<int> (len2 + 1, 0));int ans = 0;for (int i = 1; i <= len1; ++i) {for (int j = 1; j <= len2; ++j) {if (nums1[i - 1] == nums2[j - 1])dp[i][j] = dp[i - 1][j - 1] + 1;ans = max(ans, dp[i][j]);}}return ans;} };

這道題是所求的子序列是連續(xù)的,下面來一道相似的題目不連續(xù)的;

最長公共子序列

給定兩個(gè)字符串 text1 和 text2,返回這兩個(gè)字符串的最長公共子序列的長度。
一個(gè)字符串的 子序列 是指這樣一個(gè)新的字符串:它是由原字符串在不改變字符的相對順序的情況下刪除某些字符(也可以不刪除任何字符)后組成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。兩個(gè)字符串的「公共子序列」是這兩個(gè)字符串所共同擁有的子序列。
若這兩個(gè)字符串沒有公共子序列,則返回 0。

示例 1:
輸入:text1 = “abcde”, text2 = “ace”
輸出:3
解釋:最長公共子序列是 “ace”,它的長度為 3。

示例 2:
輸入:text1 = “abc”, text2 = “abc”
輸出:3
解釋:最長公共子序列是 “abc”,它的長度為 3。

示例 3:
輸入:text1 = “abc”, text2 = “def”
輸出:0
解釋:兩個(gè)字符串沒有公共子序列,返回 0。

提示:

1 <= text1.length <= 1000
1 <= text2.length <= 1000
輸入的字符串只含有小寫英文字符。

這道題就是求的不連續(xù)的公共子序列,和上一道題非常像,分析內(nèi)容也基本相同,這里就著重分析不同的地方:轉(zhuǎn)移方程;
1, dp[i][j]是長度為[0, i - 1]的字符串text1與長度為[0, j - 1]的字符串text2的最長公共子序列;(加深印象)

2,這里就分為了兩種情況:
text1[i - 1] 與 text2[j - 1]相同,text1[i - 1] 與 text2[j - 1]不相同

如果text1[i - 1] 與 text2[j - 1]相同,那么找到了一個(gè)公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;
如果text1[i - 1] 與 text2[j - 1]不相同,那就看看text1[0, i - 2]與text2[0, j - 1]的最長公共子序列(dp[i - 1][j]) 和 text1[0, i - 1]與text2[0, j - 2]的最長公共子序列(dp[i][j - 1]),取最大的。

則有dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

其它的就一樣了,代碼如下:

class Solution { public:int longestCommonSubsequence(string text1, string text2) {int len1 = text1.size(), len2 = text2.size();vector<vector<int>> dp(len1 + 1, vector<int> (len2 + 1, 0));for (int i = 1; i <= len1; ++i) {for (int j = 1; j <= len2; ++j) {if (text1[i - 1] == text2[j - 1])dp[i][j] = dp[i - 1][j - 1] + 1;elsedp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}return dp[len1][len2];} };

下面的這一道也是求不連續(xù)的子序列,但是不容易看出來,其實(shí)本質(zhì)上和最長公共子序列這一道題一模一樣;

不相交的線

在兩條獨(dú)立的水平線上按給定的順序?qū)懴?nums1 和 nums2 中的整數(shù)。

現(xiàn)在,可以繪制一些連接兩個(gè)數(shù)字 nums1[i] 和 nums2[j] 的直線,這些直線需要同時(shí)滿足滿足:

nums1[i] == nums2[j]

且繪制的直線不與任何其他連線(非水平線)相交。
請注意,連線即使在端點(diǎn)也不能相交:每個(gè)數(shù)字只能屬于一條連線。

以這種方法繪制線條,并返回可以繪制的最大連線數(shù)。

示例 1:

輸入:nums1 = [1,4,2], nums2 = [1,2,4]
輸出:2
解釋:可以畫出兩條不交叉的線,如上圖所示。
但無法畫出第三條不相交的直線,因?yàn)閺?nums1[1]=4 到 nums2[2]=4 的直線將與從 nums1[2]=2 到 nums2[1]=2 的直線相交。

示例 2:
輸入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
輸出:3

示例 3:
輸入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
輸出:2

提示:

1 <= nums1.length <= 500
1 <= nums2.length <= 500
1 <= nums1[i], nums2[i] <= 2000

直線不能相交,那么只要在字符串A中找到一個(gè)與字符串B相同的子序列,且這個(gè)子序列不能改變相對順序,那么連接相同數(shù)字的直線就不會相交。
其實(shí)就是從字符串B中找字符串A的最長公共子序列;

代碼一模一樣:

class Solution { public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {int len1 = nums1.size(), len2 = nums2.size();vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, 0));for (int i = 1; i <= len1; ++i) {for (int j = 1; j <= len2; ++j) {if (nums1[i - 1] == nums2[j - 1])dp[i][j] = dp[i - 1][j - 1] + 1;elsedp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}return dp[len1][len2];} };

總結(jié)

這類的題目多數(shù)都需要用到所給的兩個(gè)字符串或數(shù)組長度來創(chuàng)建一個(gè)二維dp數(shù)組,可以發(fā)現(xiàn)這三道題的dp數(shù)組定義幾乎是一模一樣的,所以再遇到類似的題目需要向這個(gè)方向靠攏;
還需要注意題目要求是否連續(xù),對應(yīng)著不同的處理方法;

總結(jié)

以上是生活随笔為你收集整理的最长重复子数组最长公共子序列不相交的线的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。