在给定字符串中雕刻置换的子字符串
Posted
技术标签:
【中文标题】在给定字符串中雕刻置换的子字符串【英文标题】:Carving permuted sub-strings in a given string 【发布时间】:2018-02-27 20:20:39 【问题描述】:我需要在O(n2)
时间识别 xw(w^r)y 形式的字符串,其中 xw(w^r)y 是英文字母表中的小写字符串。
这里,w^r
是 w 中字符的排列。
例如,字符串 rtedafdfa
是所需的形式,其中 x = rte, w=daf, w^r=dfa, y 是空字符串
我尝试过的:
创建了一个位置图,其中键作为字符,值作为索引列表 使用上述位置图为出现 >= 2 次的所有字符创建了一个索引列表。 对刚刚创建的索引列表进行升序排序 丢弃所有连续差不为1的索引 从最终的索引列表中划分出 w 和 w^r。上述方法在某些情况下失败了,我对我所做的一切都不满意。这是javascript中的代码:
let input = "raababaya";
let posMap = ;
for(let i=0;i<input.length;i++)
if(posMap[input[i]])
posMap[input[i]].push(i);
else
posMap[input[i]] = [i];
// O(N)
let indexList = [];
for(let char in posMap)
if(posMap[char].length >= 2)
// Has chances of permutation
indexList.push(...posMap[char]);
else
// No permutation
// Worst case O(N); Best Case O(N/2)
indexList.sort((a,b) => a-b); // nlogn
let finalPos = [];
for(let i=0;i<indexList.length;)
if(indexList[i+1] && (indexList[i+1] - indexList[i] == 1))
finalPos.push(indexList[i]);
finalPos.push(indexList[i+1]);
i += 2;
else i++;
if(finalPos.length >=4 )
// Pattern detected
let start = finalPos[0];
let end = finalPos[finalPos.length - 1];
console.log('Pattern detected');
console.log('input: ' + input);
console.log('Permutation detected: ' + input.substr(start,end));
上述代码适用于输入应用,但当字符串如下时会失败:
aaaaaaaaababaya
这应该是什么更好的方法?我正在寻找两种解决方案。一个在 N^2 次中,一个具有更好的时间复杂度。
【问题讨论】:
在这种情况下x
是什么?只是一系列小写字符?
同样适用于y
?
@EvanKnowles 是的。在raababaya
x 将是r
@EvanKnowles 是的。在raababaya
中,y 将是ya
如果可能有多种解决方案会发生什么?对于像 raabababaaya 这样的情况,y 可以是 ya 或 baaya
【参考方案1】:
我们可以通过以下方式做到这一点
-
我们不会以 xw(w^r)y 的形式计算字符串,而是搜索 xwwy,因为这是基本情况
由于 x 和 y 可以为空,我们只需要找到一个非空字符串 w 使得 ww 是输入 str 的子字符串
现在使用 2 个循环 i 和 j,检查子字符串 str(i, j) 是否为 ww 形式。如果您预先计算了频率阵列,这可以在 O(26) 中完成。
frequency[i][j] 表示子字符串 str(0,i) 中第 j 个字符的频率
如果 str(i, mid) 中字符的频率等于 str(mid+1, j) 中字符的频率,则 str(i,j) 的形式为 ww。
【讨论】:
以上是关于在给定字符串中雕刻置换的子字符串的主要内容,如果未能解决你的问题,请参考以下文章