求一个字符串的最长重复字串问题

给定一个字符串,求出这个字符串的最长重复字串,例如abcdbcd,最长重复字串是bcd。

分析:

方法1:

  一种方法是先解决http://blog.csdn.net/bertzhang/article/details/7303010的问题,在对字符串进行循环处理。

具体过程如下:

1)首先解决两个字符串的最长公共邻接子串问题;

2)将字符串,abcdbcd分成如下两个字符串的集合:

“a" 和 "bcdbcd"

"ab"和“cdbcd"

"abc"和"dbcd"

"abcd"和"bcd"-->产生最大子串bcd

“abcdb"和"cd"

"abcdbc"和"d"

完毕。

算法的复杂度是O(n^3)

方法2:

  通过后缀树来计算,循环将字符串拆分成:

abcdbcd

bcdbcd

cdbcd

dbcd

bcd

cd

d

构建一棵后缀树如下:

a-b-c-d-b-c-d

b-c-d-b-c-d

c-d-b-c-d

d

对于字符串bcd、cd等已经出现在后缀树中的字串,计算路径最长的一个字串,就是最长字串。

算法复杂度为O(n)

其实这个问题来源于web search spam中spamer在标题、anchor中堆砌重复关键词的问题。


参考文献:

http://blog.csdn.net/bertzhang/article/details/7303010

在JavaScript中,找出字符串重复最长子串可以通过多种算法实现,其中一个高效的方法是使用动态规划。下面提供一个基于动态规划的示例实现: ```javascript function longestDupSubstring(S) { const MOD = 1000000007; const base = 26; // 字母的总数 let n = S.length; let maxLen = 0; // 最长相等子串长度 let startIndex = 0; // 最长相等子串的起始索引 let hash = 0; // 当前子串的哈希值 let basePower = 1; // base的幂,用于计算新的哈希值 // 计算最大的base的n-1次幂 for (let i = 0; i < n; i++) { basePower = (basePower * base) % MOD; } // 计算字符串的哈希值 for (let i = 0; i < n; i++) { hash = (hash * base + S.charCodeAt(i) - 'a'.charCodeAt(0)) % MOD; } // 存储每个字符出现的哈希值和对应的索引 const indexMap = new Map([[hash, 0]]); // 使用滚动哈希来计算子串的哈希值 for (let i = 1; i < n; i++) { hash = (hash * base + S.charCodeAt(i) - 'a'.charCodeAt(0)) % MOD; if (indexMap.has(hash)) { let j = indexMap.get(hash); if (S.slice(j, i) === S.slice(j + maxLen, i + maxLen)) { startIndex = j; maxLen = i - j; } } else { indexMap.set(hash, i); } } // 返回最长重复子串 return S.slice(startIndex, startIndex + maxLen); } // 测试用例 console.log(longestDupSubstring("banana")); // 应该返回 "an" ``` 这段代码首先计算了字符串的哈希值,然后使用一个哈希表来存储出现过的子串哈希值及其起始索引。通过滚动窗口的方法,我们可以在O(n)的时间复杂度内找到最长重复子串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值