最长公共子数组(与子串同理)
首先注意子串和子序列的区别:
一个字符串 s 被称作另一个字符串 S 的子串,表示 s 在 S 中出现了;
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。(定义引用LeetCode 1143)
子数组与子串同理
举例:
1、s1: qwerdf, s2: qtwtetr (qwer为最长公共子序列)
2、s1:qwe, s2: qwer(qwe为最长公共子串)
解题思路
1、将两个数字一横一竖想象成一个二维矩阵 dist[A.length+1][B.length+1](+1是为了防止下标越界),i 表示 A数组的下标,j 表示 B数组的下标。i, j 共同用来遍历二维数组 dist。而 dist[i][j] 表示 A数组以第 i 个位置为尾部的数串 和 B数组以第 j 个位置为尾部的数串的最长公共子串。
2、双重for循环遍历,将 dist数组填满,
存在如下两种情况:
(1)A[i] = B[j],则dist[i][j] = dist[i][j]+1;
(2)A[i] != B[j],则dist[i][j] = 0;
最大的dist[i][j]值即为最长子串的长度。
时间复杂度O(MN),空间复杂度O(MN)。
空间复杂度是可以优化为O(2*max(M,N))的,因为每次对dist数组进行遍历是一行一行或一列一列的遍历,且只需用到上次遍历所用到的行或列。
class Solution {//未优化空间复杂度
public int findLength(int[] A, int[] B) {
int [][]dist = new int [A.length+1][B.length+1];
int num = 0;
for(int i = A.length-1;i>=0;i--) {
for(int j = B.length-1;j>=0;j--) {
if(A[i] == B[j]) {
dist[i][j] = dist[i+1][j+1]+1;
if(dist[i][j]>num) {
num = dist[i][j];
}
}
else {
dist[i][j] = 0;
}
}
}
return num;
}
}
作者:deusjin
链接:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/solution/jian-dan-yi-dong-de-dong-tai-gui-hua-fa-xin-shou-x/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:CSDN
作者:DEUSJIN
链接:https://blog.csdn.net/qq_35684046/article/details/104104418