提出的算法具有的(1 + n - (1)) + (1 + n - (2)) + (1 + n - (3)) + ... + (1 + n - (n-1)) = (n-1)*(1 + n) - (n)(n-1)/2 = (n^2 + n - 2)/2
复杂这是O(n 2 )。
因此,最好使用一个对象映射和记住字符来检查唯一性或重复。假设每个字符的最大数据大小,这个过程将是一个O(n)
算法。
function charUnique(s) {
var r = {}, i, x;
for (i=0; i<s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
在一个小小的测试案例中,函数确实运行速度快了几倍。
请注意,JavaScript字符串被定义为16位无符号整数值的序列。 http://bclary.com/2004/11/07/#a-4.3.16
因此,我们仍然可以实现相同的基本算法,但使用更快的数组查找而不是对象查找。结果现在大约快100倍。
var charRepeats = function(str) {
for (var i = 0; i <= str.length; i++) {
for (var j = i + 1; j <= str.length; j++) {
if (str[j] == str[i]) {
return false;
}
}
}
return true;
}
function charUnique(s) {
var r = {},
i, x;
for (i = 0; i < s.length; i++) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charUnique2(s) {
var r = {},
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s[i];
if (r[x])
return false;
r[x] = true;
}
return true;
}
function charCodeUnique(s) {
var r = [],
i, x;
for (i = s.length - 1; i > -1; i--) {
x = s.charCodeAt(i);
if (r[x])
return false;
r[x] = true;
}
return true;
}
function regExpWay(s) {
return /(.).*\1/.test(s);
}
function timer(f) {
var i;
var t0;
var string = [];
for (i = 32; i < 127; i++)
string[string.length] = String.fromCharCode(i);
string = string.join('');
t0 = new Date();
for (i = 0; i < 10000; i++)
f(string);
return (new Date()) - t0;
}
document.write('O(n^2) = ',
timer(charRepeats), ';<br>O(n) = ',
timer(charUnique), ';<br>optimized O(n) = ',
timer(charUnique2), ';<br>more optimized O(n) = ',
timer(charCodeUnique), ';<br>regular expression way = ',
timer(regExpWay));
可以添加将检查和预期结果的一些示例数据? –
在这种情况下什么是字符串?例如一句话还是一个字?什么是“重复”?多次发生?或者两个字母相邻? – jerdiggity
[在字符串中间重复字符]可能的重复(http://stackoverflow.com/questions/28736790/repeating-characters-in-the-middle-of-a-string) –