題目描述:
給定兩個字符串s1和s2,計算其最長公共子串的長度,並返回全部可能的最長公共子串。git
# -*- coding: utf-8 -*- # @Time : 2019-09-22 22:57 # @Author : Jayce Wong # @ProjectName : job # @FileName : longestCommonSubstring.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://github.com/SysuJayce def lcs(s1, s2): """ 如今咱們知道了,若是遇到輸入是兩個字符串的,須要用到的動態規劃的話,那麼咱們須要的狀態是一個 二維的矩陣。 首先咱們須要定義這個矩陣中每一個元素的意義: dp[i][j]表明了s1[: i + 1]和s2[: j + 1]以s1[i]和s2[j]結尾的公共子串的長度。 那麼關鍵就在於如何肯定轉換方程和如何初始化這個狀態矩陣了。 顯然,因爲dp[i][j]計算的是同時以s1[i]和s2[j]爲結尾公共子串的長度, 若是s1[i] != s2[j],那麼dp[i][j] = 0 當s1[i] == s2[j]時,dp[i][j] = dp[i - 1][j - 1] + 1 :param s1: 輸入的第一個字符串 :param s2: 輸入的第二個字符串 :return: 最大公共子串長度、以及最大公共子串的具體值 """ # 爲了方便編程,先在s1和s2前面加入一個空格佔位 s1 = ' ' + s1 s2 = ' ' + s2 rows = len(s1) cols = len(s2) dp = [[0] * cols for _ in range(rows)] maxlen = 0 for i in range(1, rows): for j in range(1, cols): if s1[i] == s2[j]: dp[i][j] = dp[i - 1][j - 1] + 1 maxlen = max(maxlen, dp[i][j]) else: dp[i][j] = 0 res = [] for i in range(1, rows): for j in range(1, cols): # s1[i]爲結尾的子串,截取長度爲maxlen便可 if dp[i][j] == maxlen: res.append(s1[i - maxlen + 1: i + 1]) return maxlen, res def main(): s1 = 'ABCBDEFBWD' s2 = 'BCBWD' maxlen, res = lcs(s1, s2) print(maxlen) print(res) if __name__ == '__main__': main()