文章目录
- 1. 两个字符串的最小ASCII删除和(712)
- 2. 最长重复子数组(718)
1. 两个字符串的最小ASCII删除和(712)
题目描述:
状态表示:
根据经验以及题目要求,建立二维数组dp,使用dp[i][j]表示s1字符串0到i区间内以及s2字符串0到j区间内的拥有最大ASCII码值的公共子序列。这里使用到了反向思考的思想,仔细看一下题目要求使得两个字符串相等所需删除字符的最小ASCII码值,反过来想就是要求保留下来的公共子序列的ASCII码值最大。
状态转移方程:
这里的状态还是根据s1字符串在0到i区间内以及s2字符串在0到j区间内的最后一个字符进行分析。当s1[i]以及s2[j]都在公共的子序列中,如果满足s1[i]==s2[j],那么dp[i][j]=dp[i-1][j-1]+s1[i]。当s1[i]在公共的子序列中,s2[j]不在公共子序列中,那么可以得到dp[i][j]=dp[i][j-1],其实这里的状态转移方程并不准确,因为dp[i][j-1]也包含s1[i]不在公共的子序列中,s2[j]也不在公共子序列中这种情况,但是没关系因为dp数组的每个值求的是最大值,不怕重复。当s1[i]不在公共的子序列中,s2[j]在公共子序列中,那么可以得到dp[i][j]=dp[i-1][j],这里和上一种情况是类似的,也包含了s1[i]不在公共的子序列中,s2[j]也不在公共子序列中这种情况。最后一种情况就是1[i]不在公共的子序列中,s2[j]也不在公共子序列中,dp[i][j]=dp[i-1][j-1]。
初始化:
为了防止数组越界以及方便运算,给二维数组dp加上第0行以及第0列。这里的第0行和第0列分别代表s1和s2为空串,很好理解,既然为空串就别谈公共子序列的最大ASCII码值了,肯定都是0,因此全部赋为0即可。
填表顺序:
从上至下,从左至右。
返回值:
这里的返回值比较特殊,需要先将s1和s2两个字符串的ASCII码值相加起来之后再减去2*dp[m][n]。
代码如下:
class Solution {
public int minimumDeleteSum(String s1, String s2) {
int m = s1.length();
int n = s2.length();
int[][] dp = new int[m + 1][n + 1];
int max = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + (int) s1.charAt(i - 1);
}
dp[i][j] = Math.max(dp[i][j], Math.max(dp[i][j - 1], dp[i - 1][j]));
max = Math.max(max, dp[i][j]);
}
}
int ret = 0;
for (int x :
s1.toCharArray()) {
ret += x;
}
for (int x :
s2.toCharArray()) {
ret += x;
}
return ret - 2 * max;
}
}
题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)
2. 最长重复子数组(718)
题目描述:
状态表示:
根据题目要求以及经验,建立二维数组dp,使用dp[i][j]表示两个数组分别在0到i区间以及0到j区间的以i及j位置元素为结尾的最长的公共子数组的长度。
状态转移方程:
子数组问题状态转移方程很简单,分析区间内的最后一个元素,如果0到i区间内最后一个元素和0到j区间内最后一个元素相等,那么dp[i][j]=dp[i-1][j-1]+1,如果不相等,dp[i][j]=0。
初始化:
初始化也还是一样,为了避免越界,给dp加上第0行和第0列,第0行和第0列全部赋为0。因为第0行和第0列是分别代表nums1为空数组以及nums2为空数组,那么这样肯定得不到公共子数组,更别提长度了。
填表顺序:
从上到下,从左至右。
返回值:
dp数组中最大值。
代码如下:
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int[][] dp = new int[m + 1][n + 1];
int max = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = 0;
}
max = Math.max(max, dp[i][j]);
}
}
return max;
}
}
题目链接
时间复杂度:O(N^2)
空间复杂度:O(N^2)