例如
此时最长重复子数组就是1 2 3, 长度为3
首先用暴力解法思考,按照每一个元素位依次比较,时间复杂度为n3,包括大量重复计算。将暴力解法的每一步记录在二维数组中, 省略了重复比较,以上例作为参考,二维数组构造如下:
1 2 3 6 7
5 0 0 0 0 0
8 0 0 0 0 0
1 1 0 0 0 0
2 0 2 0 0 0
3 0 0 3 0 0
从二维数组中可以看出最长子数组为3
令数组一为str1,数组二为str2,则 dp[ i ] [ j ]的数值意义是,以数组str1[ i ]结尾和数组二以str2[ j ]结尾的子数组中重复的数组长度最长为多少。
每次数组移动有两种情况
如果是相同则在dp[ i - 1 ] [ j - 1 ]的基础上加一,否则归零,因为不接受不连续的相同子数组,这里已经截断。
#include
#include//最长重复子数组
int main() {char str1[30];char str2[30];scanf("%s%s", str1, str2);int arr[10][10];int count1 = strlen(str1);int count2 = strlen(str2);for (int i = 0; i < count1; i ++) {//初始化第一行if (str1[i] == str2[0]) {arr[0][i] = 1;}else {arr[0][i] = 0; }}for (int i = 0; i < count2; i ++) {//初始化第一列if (str2[i] == str1[0]) {arr[i][0] = 1;}else {arr[i][0] = 0;}}for (int i = 1; i < count2; i ++) {//arr[i][j] = arr[i - 1][j - 1] OR 0for (int j = 1; j < count1; j ++) {if (str1[j] == str2[i]) {arr[i][j] = arr[i - 1][j - 1] + 1;}else {arr[i][j] = 0;}}}int result = 0;for (int i = 0; i < count2; i ++) {for (int j = 0; j < count1; j ++) {if (arr[i][j] > result) {result = arr[i][j];}}}printf("%d", result);return 0;
}
例如
此时最长重复子数组就是1 2 3 4, 长度为4
首先用暴力解法思考,按照每一个元素位依次比较,时间复杂度为n3,包括大量重复计算。将暴力解法的每一步记录在二维数组中, 省略了重复比较,以上例作为参考,二维数组构造如下:
1 2 3 6 7 4
5 0 0 0 0 0 0
8 0 0 0 0 0 0
1 1 1 1 1 1 1
2 1 2 2 2 2 2
3 1 2 3 3 3 3
4 1 2 3 3 3 4
从二维数组中可以看出最长子数组为4
令数组一为str1,数组二为str2,则 dp[ i ] [ j ]的数值意义是,以数组str1[ i ]结尾和数组二以str2[ j ]结尾的子数组中重复的数组长度最长为多少。
每次数组移动有两种情况
如果是相同则在dp[ i - 1 ] [ j - 1 ]的基础上加一,否则变为 MAX {dp[ i ] [ j - 1], dp[ i - 1] [ j ] },因为接收不连续的子序列,最大值是继承的。
#include
#includeint max(int x, int y) {if (x > y) {return x;}else {return y;}
}int main() {char str1[30];char str2[30];scanf("%s%s", str1, str2);int count1 = strlen(str1);int count2 = strlen(str2);int arr[30][30];if (str1[0] == str2[0]) {arr[0][0] = 1;}else {arr[0][0] = 0;}for (int i = 1; i < count1; i ++) {//初始化第一行if (str1[i] == str2[0]) {arr[0][i] = 1;}else {arr[0][i] = max(arr[0][i - 1], 0);}}for (int i = 1; i < count2; i ++) {//初始化第一列if (str2[i] == str1[0]) {arr[i][0] = 1;}else {arr[i][0] = max(arr[i - 1][0], 0);}}for (int i = 1; i < count2; i ++) {//推导矩阵for (int j = 1; j if (str1[j] == str2[i]) {arr[i][j] = arr[i - 1][j - 1] + 1;}else {arr[i][j] = max(arr[i - 1][j], arr[i][j - 1]);}}}printf("%d", arr[count2 - 1][count1 - 1]);return 0;
}
对于最长重复子数组,结果需要连续,所以遇到不一样的字符时需要从0开始。对于后者仅需要相同次序,所以每一个字符继承前端结果。