提出的算法具有的(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) –