目录
题目
解题思路
滑动窗口
思路
代码
结果
DP
思路
代码
结果
今天下午休息,合租的小伙伴陪女票出去玩了,在家闲来无事就随便刷刷LeetCode每日一题吧,结果推送给我的是一道难度中等的题,这是在侮辱我的智商吗?可后面的解题过程告诉我,我智商不用它来侮辱也是负数。话不多说,上题目。
一看到这题,我生锈的脑子第一反应就是暴力暴力暴力,暴力的时间复杂度为O(n3),最后的提交结果也毫无意外地超时了。
言归正传,再仔细阅读了一下题目,“公共的”、“长度最长的”这几个字眼再结合本题,不就在暗示我们用滑动窗口嘛。
先上1张GIF图便于理解
两个字符串分别为A串和B串
1. 以A串为基准,B串向后滑动,每滑动一次比较两者公共部分(窗口)的元素,若连续相同则连续进行ret+1,若不同则ret不变。
2. 以B串为基准,A串向后滑动,每滑动一次比较两者公共部分(窗口)的元素,若连续相同则连续进行ret+1,若不同则ret不变。
3. 最后取两个ret最大值。
做完之后看了下题解,发现也可以用动态规划,而且这题用动态规划做还挺简单的,状态转移方程简单得一腿。
令 dp[i][j] 表示 A[i:] 和 B[j:] 的最长公共前缀,那么答案即为所有 dp[i][j] 中的最大值。如果 A[i] == B[j],那么 dp[i][j] = dp[i + 1][j + 1] + 1,否则 dp[i][j] = 0。(这里借用了 Python 表示数组的方法,A[i:] 表示数组 A 中索引 i 到数组末尾的范围对应的子数组。)
考虑到这里 dp[i][j] 的值从 dp[i + 1][j + 1] 转移得到,所以我们需要倒过来,首先计算 dp[len(A) - 1][len(B) - 1],最后计算 dp[0][0]。
以题目中的输入为例
A: [1,2,3,2,1] B: [3,2,1,4,7]
状态转移方程为:
若 A[i] != B[j] , dp[i][j] = 0 若 A[i] == B[j] , dp[i][j] = dp[i+1][j+1] + 1
动态规划矩阵如下表所示:
32147100100201000330000202000100100
结果即为矩阵中的最大值3
————————————————————————————————————————
烦躁啊,被疫情搞得左右为难,不知道怎么选择,到底出国还是国内还是HK还是工作,办CAS又被学校卡了,说要提供之前KCL Summer Course的CEFR/RQF Level证明,没有证明也要提供没有证明的证明,英国人办事真的死板,呵呵哒。。