97. 交错字符串
题目
- 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
例题
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
输出: true
输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbbaccc”
输出: false
理解
:字符串问题用动态规划,逐步思考和上一个字符串的关系
字符串画表,进行路径规划
dp[i][j] = dp[i-1][j]&&s1[i-1]==s3[i+j-1] || dp[i][j-1]&&s2[j-1]==s3[i+j-1];
画表画表
解题

- 初始化列表
- 路径规划——两条路径,前提条件的保证和选择
- dp[i][j] =
dp[i-1][j]&&s1[i-1]==s3[i+j-1]
|| dp[i][j-1]&&s2[j-1]==s3[i+j-1]
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| bool isInterleave(string s1, string s2, string s3) { if (s1.size() + s2.size() != s3.size()) return false;
int n = s1.size(); int m = s2.size(); vector<vector<bool>>dp(n + 1, vector<bool>(m + 1, false));
dp[0][0] = true; for (int i = 1; i < n + 1; i++) { dp[i][0] = dp[i - 1][0] && s1[i - 1] == s3[i - 1]; } for (int i = 1; i < m + 1; i++) { dp[0][i] = dp[0][i - 1] && s2[i - 1] == s3[i - 1]; }
for (int i = 1; i < n + 1; i++) { for (int j = 1; j < m + 1; j++) { dp[i][j] = dp[i - 1][j] && s1[i - 1] == s3[i + j - 1] || dp[i][j - 1] && s2[j - 1] == s3[i + j - 1]; } } return dp[n][m]; }
|
类似题目
416. 分割等和子集
题目
- 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
例题
输入: [1, 5, 11, 5]
输出: true
解释: 数组可以分割成 [1, 5, 5] 和 [11].
输入: [1, 2, 3, 5]
输出: false
解释: 数组不能分割成两个元素和相等的子集.
理解
:让集合元素相加 target = sum / 2
动态规划:对于依次使用集合中元素,考虑所有能组合成的可能性
dp[ i ][ j ] = dp[ i-1 ][ j ] || nums[ i ]==j || dp[ i-1 ][ j - nums[i]]
1.上可以,下不加也一定可以
2.当num[i] =j时也一定可以
3.当 j>nums[i]时,dp[i-1][j-nums[i]]也为真时,其也为真
画表画表

- 初始化列表
- 路径规划——三种可能,前提条件的保证和选择
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| bool canPartition(vector<int>& nums) { int n = nums.size(); if (n <= 1)return false;
int sum = 0; for (auto it : nums) { sum += it; } if (sum % 2 == 1)return false; int target = sum / 2;
vector<vector<bool>>dp(n, vector<bool>(target + 1, 0)); dp[0][0] = true;
if (nums[0] <= target) { dp[0][nums[0]] = true; }
for (int i = 1; i < n; i++) { for (int j = 0; j < target + 1; j++) {
dp[i][j] = dp[i - 1][j]; if (nums[i] <= j) { dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]]; } } if (dp[i][target]) { return true; }
} return dp[n - 1][target]; }
|
72. 编辑距离
题目
:给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
- 你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
例题

解题
三种移动方法:1.删除 2. 替换 3.插入
删除和替换和插入操作数是一样的为1,但是当插入的新字符 = 对应字符,操作数为0

1.初始化 dp[i][0] = i;
2.
int temp1 = dp[i-1][j] + 1;
int temp2 = dp[i][j-1] + 1;
int temp3 = dp[i-1][j-1];
if(word1[i-1]!= word2[j-1])temp3++;
- dp[i][j] = min(temp1,min(temp2,temp3));
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| int minDistance(string word1, string word2) { int len1 = word1.size(); int len2 = word2.size();
if (len1*len2 == 0)return max(len1, len2);
vector<vector<int>>dp(len1 + 1, vector<int>(len2 + 1));
for (int i = 0; i < len1 + 1; i++) { dp[i][0] = i; } for (int i = 0; i < len2 + 1; i++) { dp[0][i] = i; } for (int i = 1; i < len1 + 1; i++) { for (int j = 1; j < len2 + 1; j++) { int temp1 = dp[i - 1][j] + 1; int temp2 = dp[i][j - 1] + 1; int temp3 = dp[i - 1][j - 1]; if (word1[i - 1] != word2[j - 1]) temp3++; dp[i][j] = min(temp1, min(temp2, temp3)); } } return dp[len1][len2]; }
|
1143. 最长公共子串
题目
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
例如,”ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
- 输入:text1 = “abcde”, text2 = “ace”
- 输出:3
- 解释:最长公共子序列是 “ace”,它的长度为 3。
- 输入:text1 = “abc”, text2 = “def”
- 输出:0
- 解释:两个字符串没有公共子序列,返回 0。
- 初始化dp [0][ i ] = 0 dp [ j ][0] = 0
- dp方程
if(text1[ i-1 ]=text2[ j-1])
dp[ i ][ j ] = dp[i-1 ][ j-1 ] +1;
else
dp[ i ][ j ] = max(dp[i-1 ][ j ],dp[i ][ j-1 ];)

代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int longestCommonSubsequence(string text1, string text2) { int m = text1.size(); int n = text2.size(); vector<vector<int>>dp(m + 1, vector<int>(n + 1, 0)); for (int i = 1; i < m + 1; i++) { for (int j = 1; j < n + 1; j++) { if (text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]); } } return dp[m][n]; }
|
718.最长重复子数组
题目
:
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
例题
:
- 输入:
- A: [1,2,3,2,1]
- B: [3,2,1,4,7]
- 输出:3
- 解释:
- 长度最长的公共子数组是 [3, 2, 1] 。
