解法1 搜索
可以证明,要判断一个数列3,5,1是否在母数列中出现过,可以先找出3在母数列中最先出现的地方,然后从这个地方开始,找5最先出现的地方,然后再找这个地方之后1最先出现的地方,如果都能找到,则该串是这个母串的子串,否则不是.
因此可以预先做一个预处理,用next[I,j]表示从母串第i个数字开始,数字j最先出现在母串的第几个元素处.然后长度不断加一,逐个构造当前长度的字串并判断是否为母串的一个子串,当搜索到第一个非子串时跳出.这就是所谓的DFS-ID(迭代加深搜索).
预处理的时间复杂度为O(nq),这个思想很值得借鉴.
解法2 DP-O(nq)
在解法1枚举长度时,可以随时保存当前符合的子串的最长长度,当长度加一时,只需从这个长度开始就可以了.这个叫记忆化搜索,也即DP
或者,用f(i,j)表示长度为i,最后一个数字为j的子串最早结束于母串的什么位置,那么状态转移方程为:f(i,j)=max{f[i-1,j]}+next[max{f[i-1,j]},j].
|