最近遇到很多這種類型的題目,都是需要用到動態規劃解決的,在此將這一類型的題目都更新出來,方便大家和我一起學習 ^ _ ^
.
相關博文鏈接:
LeetCode算法 —— 正則表達式匹配(詳解官方動態規劃思想)
題目:
最大公共子串長度問題就是:
求兩個串的所有子串中能夠匹配上的最大長度是多少。
比如:“abcdsdjflkas” 和 “abdabcdd”,
可以找到的最長的公共子串是"abcd", 所以最大公共子串長度爲4。
解題思想:此題和前文的正則表達式匹配的思想是差不多的,都是使用一個二維數組當作一個標誌存儲容器,arr[i][j] 表示 Str 中的第 i 個字符是否和 SubStr 中的第 j 個字符相同,如若相同,並且 arr[i - 1][j - 1] 也相同,則我們將它們作上一個數字上的標記,用來表明最大子串長度是多少 . . .
比如我們開闢一個數組大小是 12 * 12,裏面的每一個元素都是 兩個串中元素的對應關係
例如這個圖如下所述:
代碼如下所示:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int GetMaxSubStr(string Str, string subStr) {
int iSize = Str.size();
int jSize = subStr.size();
int len = iSize > jSize ? iSize : jSize; // 找出比較長的串的大小
int MaxSize = 0; // 最大的公共子串大小
// 動態規劃思想
vector<vector<int> > arr(len + 1, vector<int>(len + 1));
for (size_t i = 1; i <= iSize; i++)
{
for (size_t j = 1; j <= jSize; j++)
{
// 判斷當前匹配的字符是否相等
if (Str[i - 1] == subStr[j - 1])
{
// 當前的匹配結果 等於前一個字符 i - 1 j - 1 匹配結果 + 1
arr[i][j] = arr[i - 1][j - 1] + 1;
if (MaxSize < arr[i][j]) // 時刻更新最大的公共子串大小
MaxSize = arr[i][j];
}
}
}
return MaxSize; // 返回最大值
}
}
測試代碼就不演示了,這裏的代碼不長,並且非常的有趣,簡單的幾行代碼就可以把這個字符串之間的關係給搞清楚 . . .
這裏的核心代碼只有一句:
arr[i][j] = arr[i - 1][j - 1] + 1;
如果看懂的小夥伴可以直接點贊關閉了,哈哈 ^ _ ^
我們可以這樣理解: 比如 abcd 和 abXX 這兩個串,現在的 arr[i][j] 中的 i 表示第一個串 b 這個字符, j 表示第二個串 b這個符,現在我們判斷完這兩個字符是相等的,然後我們執行上面的這條語句,
在 b 與 b 判斷相等之前,我們已經把 a 與 a 判斷成功了
,也就是現在的 arr[i - 1][j - 1] 這個標誌已經有值了,假設這個值爲 1(當前的目標也確實是 1),所以我們的 arr[i][j] 的值現在是 1 + 1 == 2
單個匹配圖解過程
我們將每一個 Str中的字符 與 SubStr中的所有字符進行匹配之後產生的圖如下所示:
1)Str 中的 a:
2)Str 中的 b:
3)Str 中的 c:
3)Str 中的 d:
此處已經結束了,下面我就不一一演示了,大家可以自行測試 . . .
.