NC55 最长公共前缀 描述 给你一个长度为 $n$ 的字符串数组 $strs$,编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。
解法1:纵向扫描 先得到最短的字符串,然后用最短的字符串去一一比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution : def longestCommonPrefix (self , strs ): if len (strs) == 0 : return "" strs.sort(key=lambda x:len (x)) min_len = len (strs[0 ]) temp = strs[0 ] res = "" for i in range (1 ,min_len+1 ): flag = True for cur_str in strs: if temp[:i] != cur_str[:i]: flag = False break if flag == True : res = temp[:i] return res
NC17 最长回文子串 描述 对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A 以及它的长度n ,请返回最长回文子串的长度。
解法一:动态规划
参考题解:题解 | #最长回文子串#_牛客博客 (nowcoder.net)
定义 dp[i][j]
表示 A[i:j]
是否为回文串。
外循环从后向前遍历,i ->[6 0]
内循环从 i
开始向后遍历,直接结束。
每轮内循环的第一次循环可以解决 单个字符的回文串。
每次循环由外向内检测字串是否为回文串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution : def getLongestPalindrome (self, A, n ): dp = [ [0 for _ in range (n)] for _ in range (n) ] max_len = 0 for i in range (n-1 ,-1 ,-1 ): for j in range (i,n): cur_len = j- i +1 print (A[i:j+1 ],i,j,A[i],A[j],cur_len) if A[i] == A[j]: if cur_len <= 2 : dp[i][j] = 1 else : dp[i][j] = dp[i+1 ][j-1 ] if dp[i][j]: print (dp[i][j]) max_len = max (max_len,cur_len) return max_len
NC127 最长公共字串 描述 给定两个字符串str1和str2,输出两个字符串的最长公共子串
题目保证str1和str2的最长公共子串存在且唯一。
解法:暴力解法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution : def LCS (self , str1 , str2 ): len1 = len (str1) len2 = len (str2) if len1 < len2: min_len = len1 min_str = str1 max_str = str2 else : min_len = len2 min_str = str2 max_str = str1 global_max_str = "" for i in range (min_len-1 ,-1 ,-1 ): for j in range (i,min_len): cur_str = min_str[i:j+1 ] if cur_str in max_str: if len (global_max_str) < len (cur_str): global_max_str = cur_str print (str2[i:j+1 ]) return global_max_str
解法:动态规划 参考评论区:
【数据结构和算法】动态规划解最长公共子串_牛客博客 (nowcoder.net)
注意这题求的是最长公共子串,不是最长公共子序列,子序列可以是不连续的,但子串一定是连续的。
定义 dp[i][j]
表示字符串 str1
中的第 i
个字符和 str2
中 第 j
个字符为最后一个元素所构成的最长公共字串。
如果要求 dp[i][j]
,也就是 str1
的第 i
个字符和str2
的第j
个字符为最后一个元素所构成的最长公共字串,我们首先需要判断这两个字符是否相等。
其重点是,以i,j分别是str1,str2的结束字符串,当前的结尾字符记录,会在前一个字符记录上进行迭代,同时在迭代过程中记录字串长度,并记住结束位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution : def LCS (self , str1 , str2 ): maxLength = 0 maxLastIndex = 0 len1 = len (str1) len2 = len (str2) dp = [ [0 for _ in range (len2+1 )] for _ in range (len1+1 ) ] for i in range (len1): for j in range (len2): if str1[i] == str2[j]: dp[i+1 ][j+1 ] = dp[i][j] + 1 if dp[i+1 ][j+1 ] > maxLength: maxLength = dp[i+1 ][j+1 ] maxLastIndex = i else : dp[i+1 ][j+1 ] = 0 res = str1[maxLastIndex-maxLength+1 :maxLastIndex+1 ] return res
解法二:优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 maxLastIndex = 0 maxLength = 0 len1 = len (str1) len2 = len (str2) dp = [0 for _ in range (len2+1 )] for i in range (0 ,len1): for j in range (len2-1 ,-1 ,-1 ): if str1[i] == str2[j]: dp[j+1 ] = dp[j] + 1 if dp[j+1 ] > maxLength: maxLength = dp[j+1 ] maxLastIndex = i else : dp[j+1 ] = 0 res = str1[maxLastIndex-maxLength+1 :maxLastIndex+1 ] return res