String 求K的最大值,使子序列A和B存在,并应满足上述条件
给定长度为String 求K的最大值,使子序列A和B存在,并应满足上述条件,string,algorithm,data-structures,dynamic-programming,String,Algorithm,Data Structures,Dynamic Programming,给定长度为n的字符串S。选择一个整数K和两个长度K的非空子序列A和B,使其满足以下条件: A=B即对于每个i而言,A中的ith字符与B中的ith字符相同 让我们将用于构造A的索引表示为a1、a2、a3,…,其中ai属于s和B表示为b1、b2、b3,…,bn其中bi属于s。如果我们用M表示A和B中的公共索引数,则M+1最大长度子串的解决方案如下: 在构建一个模型之后,您可以导出。LCP数组中的最大值对应于您要查找的K。这两种结构的总体复杂性是O(n) 后缀数组将按升序对字符串中的所有前缀进行排序。
n
的字符串S
。选择一个整数K
和两个长度K
的非空子序列A
和B
,使其满足以下条件:
A=B
即对于每个i
而言,A
中的ith
字符与B
中的ith
字符相同李>
A
的索引表示为a1、a2、a3,…,其中ai属于s
和B
表示为b1、b2、b3,…,bn
其中bi属于s
。如果我们用M
表示A
和B
中的公共索引数,则M+1最大长度子串的解决方案如下:
在构建一个模型之后,您可以导出。LCP数组中的最大值对应于您要查找的K。这两种结构的总体复杂性是O(n)
后缀数组将按升序对字符串中的所有前缀进行排序。然后,最长公共前缀数组计算排序后的后缀数组中所有连续后缀对之间的最长公共前缀(LCP)的长度。因此,该数组中的最大值对应于S的两个最大长度子字符串的长度
有关使用“香蕉”一词的好例子,请查看(更新:请参阅O(n)
)
我们可以修改经典的递归,以获得一个额外的参数
我希望JavaScript代码(不是备忘录)是不言自明的:
函数f(s,i,j,f){
if(i<0 | | j<0)
返回值?0:-无穷大
如果(s[i]==s[j]){
如果(不常见){
返回1+f(s,i-1,j-1,真)
}else如果(i==j){
返回Math.max(
1+f(s,i-1,j-1,假),
f(s,i-1,j,假),
f(s,i,j-1,假)
)
}否则{
返回1+f(s,i-1,j-1,真)
}
}
返回Math.max(
f(s,i-1,j,j),
f(s、i、j-1、f)
)
}
var s=“aabcde”
log(f(s,s.length-1,s.length-1,false))
我删除了以前的答案,因为我认为我们不需要类似LCS的解决方案(LCS=最长公共子序列)
找到在一个字符中不同且共享所有其他字符的两个子序列(A,B)就足够了
下面的代码在O(N)时间内找到解决方案
当从i到字符串末尾的所有字符都不同时,dp[i]
等于0
我将通过一个例子来解释我的代码
对于“abcack”
,有两种情况:
- 第一个
'a'
将由两个子序列a
和B
共享,在这种情况下,解决方案将是=1+函数(“bcack”)
- 或者
'a'
不会在a
和B
之间共享。在这种情况下,结果将是1+“ck”
。为什么1+“ck”
?这是因为我们已经满足了M+1我相信我们只是在寻找最接近的相等字符对,因为A和B中排除的唯一字符将是该对中的一个字符以及介于两者之间的任何字符
下面是JavaScript中的O(n)
:
函数f(s){
设map={}
让best=-1
对于(设i=0;iSince K仅用作上界,其最大值是无限的。K=无穷大,A=B=S。您可能在问题中犯了一个错误。@MattTimmermans,但K>M,因此我们不能让A=B=S@MattTimmermans我认为问题在于,对于给定的stringA,K是一个简单的算法,它只会尝试所有不同的起始位置在字符串中,查看相同的结果字符的数量。最坏的情况是O(n^3)。这足够好吗,或者您需要找到最佳算法?@valdo您能更简单地告诉我naive算法将如何工作吗?您能告诉我算法将如何工作吗?例如,如果s=anxa
。确定:后缀数组将是[3,0,1,2](意思是[“a”,“anxa”,“nxa”,“xa”]),你可以从中得到的LCP是[0,1,0,0],它告诉你“a”和“anxa”有一个长度为1的共同前缀。因此S=anxa
的最大值是K=1
。谢谢你的问题不需要子序列而不是子序列吗?例如,“baa”是“banana”的子序列但不是一个子串。@ MyRTLCAT确实,谢谢你指出。我会在我的答案中强调这一点。你能解释一下这个算法是如何工作的吗?有什么想法?变量<代码>的意义是什么?如果我们还没有一个和<代码> i==j< /代码>,我们必须考虑选择将该点标记为解决方案的一部分可能导致一个无效的,因此我们将分支添加到递归中,以允许我们找到至少一个地方:<代码> Ai==Bi和<代码> i!=j< /代码> @ SurajSh > @arma(更正我先前的评论)问题条件规定A和B至少有一个不常见的索引(其中Ai==Bi和i!=j
)由于M+1不能大于K。由于子问题重叠,您给出的解决方案具有指数时间复杂性,我尝试了动态规划,但得到了错误的答案。您能告诉我递归方程和基本情况吗?该算法没有为案例aaababcd
,aebgaseb
aaababcd
的ode>K
输出是6
而是7
,K
对于aebgaseb
的输出是3
而应该是4
。算法不是协同的
def function(word):
dp = [0]*len(word)
lastOccurences = {}
for i in range(len(dp)-1, -1, -1):
if i == len(dp)-1:
dp[i] = 0
else:
if dp[i+1] > 0:
dp[i] = 1 + dp[i+1]
elif word[i] in lastOccurences:
dp[i] = len(word)-lastOccurences[word[i]]
lastOccurences[word[i]] = i
return dp[0]