Algorithm 按顺序查找包含相同频率字母的最长子序列

Algorithm 按顺序查找包含相同频率字母的最长子序列,algorithm,Algorithm,这是2019年澳大利亚信息学奥林匹克竞赛的一个问题: 在你最新的神秘DNA研究项目成功后,你吸引了一个最邪恶的生物的注意:美杜莎。美杜莎有蛇而不是头发。她的每一条蛇的DNA都由一个大写字母串表示。每个字母都是S、N、A、K或E中的一个。你广泛的研究表明,蛇的毒液水平取决于它的DNA。如果蛇的DNA为: •有5个字母•以字母S的x个副本开始 •然后有x份字母N的副本 •然后有x份字母A的副本 •然后有x份字母K的副本 •以字母E的x份副本结尾 例如,毒液级别为1的蛇具有DNA snake,而毒液级

这是2019年澳大利亚信息学奥林匹克竞赛的一个问题:

在你最新的神秘DNA研究项目成功后,你吸引了一个最邪恶的生物的注意:美杜莎。美杜莎有蛇而不是头发。她的每一条蛇的DNA都由一个大写字母串表示。每个字母都是S、N、A、K或E中的一个。你广泛的研究表明,蛇的毒液水平取决于它的DNA。如果蛇的DNA为:

•有5个字母•以字母S的x个副本开始

•然后有x份字母N的副本

•然后有x份字母A的副本

•然后有x份字母K的副本

•以字母E的x份副本结尾

例如,毒液级别为1的蛇具有DNA snake,而毒液级别为3的蛇具有DNA sssnnaakkeee。如果蛇的DNA不符合上述格式,则其毒液水平为0。美杜莎希望你能帮她从蛇的DNA中删除零个或多个字母,让她的蛇变得有毒。根据一条蛇的DNA,你能计算出这条蛇的最大毒液量吗


是否可以使用二进制搜索来获得复杂度为O(nlogn)的算法?

是的,您可以使用二进制搜索来搜索最大毒液浓度

最初:
l=0
r=n

当一些
m=(l+r+1)/2
我们可以检查
O(n)
时间,如果我们可以获得这样的毒液级别m,只需先取
m
字母
S
然后取下m个字母
n
等等。如果没有足够的字母,我们将搜索间隔更新为
r=m-1
,否则
l=m

示例:假设输入是
snakessnnaake

  • 二进制搜索初始值:
    l=0
    r=15
  • l=0
    r=15
    m=(l+r+1)/2=8
  • 我们无法获得毒液值8,因此
    r=m-1=7
  • l=0
    r=7
    m=(l+r+1)/2=4
  • 我们无法获得毒液值4,因此
    r=m-1=3
  • l=0
    r=3
    m=(l+r+1)/2=2
  • 我们可以得到毒液值2,所以
    l=m=2
  • l=2
    r=3
    m=(l+r+1)/2=3
  • 我们无法获得毒液值3,因此
    r=m-1=2
  • 现在由于
    l==r
    我们终止了二进制搜索,并得出结论:答案是
    2

  • 线性时间,线性空间:

    假设输入字符串的长度为n。制作一个5xn数组,其中5行表示输入数组中每个索引的S、N、a、K、E的累积计数。让我们将这些行称为
    s
    N
    A
    K
    E

    跟踪5个索引,让我们称它们为
    s
    n
    a
    k
    e

    Increment `s` until `S[s]` increases by 1 (possibly at s=0). 
    Increment `n` until `N[n]-N[s]=S[s]`.
    Increment `a` until `A[a]-A[n]=S[s]`.
    Increment `k` until `K[k]-K[a]=S[s]`.
    Increment `e` until `E[e]-E[k]=S[s]`.
    
    尽可能多地重复。我们能够满足增量步骤的最终数字给出了答案

    数组中有5n个索引,我们只增加它们,所以这在n中是线性的

    有一些明显的优化可以改善这一点,但它不能超越线性


    线性时间,恒定空间

    我们将使用与前面相同的索引名,但将让大写字母表示S的累积发生率,N在最后S之后,K在最后N之后,依此类推

    Set `s` to the first index where an S appears.
    Set `n` to `s`, and increment until we get an N.
    Set `a` to `n`, and increment until we get an A.
    Set `k` to `a`, and increment until we get an K.
    Set `e` to `k`, and increment until we get an E.
    
    现在,重复执行以下操作:


    每次我们在索引中找到匹配的字母时,递增
    s
    ,直到我们得到另一个s,递减
    N
    A
    K
    E
    ,您能举个例子说明在初始搜索后如何更新间隔吗?ThanksIt不能超越线性时间进行改进,尽管它可以成为恒定的空间。