在给定字符串

时间:2017-09-19 06:55:22

标签: javascript string algorithm anagram

我需要在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时间,一个具有更好的时间复杂度。

1 个答案:

答案 0 :(得分:0)

我们可以通过以下方式实现

  1. 而不是以 xw(w ^ r)y 的形式计算字符串,而是搜索 xwwy ,因为这是基本情况
  2. 由于x和y可以为空,我们只需找到一个非空字符串w,这样ww就是输入str的子字符串
  3. 现在使用2个循环i和j,检查子串str(i,j)是否为ww形式。如果您预先计算了频率数组,则可以在 O(26)中完成此操作。
  4. frequency [i] [j]表示子串str(0,i)中第j个字符的频率
  5. 如果str(i,mid)中的字符频率等于str(mid + 1,j)中的字符频率,则
  6. str(i,j)的格式为 ww