最长公共子数组(与子串同理)

人盡茶涼 提交于 2020-01-29 11:18:27

最长公共子数组(与子串同理)

首先注意子串和子序列的区别:

一个字符串 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!