我无法理解以下解决方案是O(1)空间而不是O(n)空间。编码挑战如下:
编写一个仅对字符串进行一次迭代并使用O(1)额外内存的解决方案,因为这是您在真正的面试中要做的。
给出一个字符串s,在其中找到并返回一个非重复字符的第一个实例。如果没有这样的字符,则返回“ _”。
以下是O(1)空间的解决方案。
function firstNotRepeatingCharacters(s: string) : string {
const chars: string[] = s.split('');
let duplicates = {};
let answer = '_';
let indexAnswer = Number.MAX_SAFE_INTEGER;
chars.forEach((element, index) => {
if(!duplicates.hasOwnProperty(element)) {
duplicates[element] = {
count: 1,
index
}
} else {
duplicates[element].count++;
duplicates[element].index = index;
}
});
for(const key in duplicates) {
if(duplicates[key].count === 1 && duplicates[key].index < indexAnswer) {
answer = key;
indexAnswer = duplicates[key].index;
}
}
return answer;
}
console.log(firstNotRepeatingCharacter('abacabad'));
console.log(firstNotRepeatingCharacter('abacabaabacaba'));
我不明白上面的解决方案是O(1)空间。由于我们遍历数组,因此将每个元素映射到一个对象(重复)。我认为这将被视为O(n),有人可以为我澄清一下这是O(1)。谢谢。
答案 0 :(得分:4)
内存使用量与字符串中不同字符的数量成比例。不重复字符的数量上限为52(或其他一些 finite 值),并且一旦每个不重复字符都具有 n 增加,潜在的内存使用量就不会增加被看到。
因此,内存使用量存在一个恒定的上限(不取决于 n ),因此内存使用量为O(1)。
答案 1 :(得分:1)
该算法具有 O(min(a,n))空间复杂度(其中 a 是用于文本编码的字母数,例如用于UTF8 a> 1M )。最坏的情况是:带有唯一字符的字符串(在这种情况下为 n <= a ),例如abcdefgh
duplicates
对象具有与输入字符串的数字字母相同的键数-在这种情况下很明显,已用内存的大小取决于 n 。
O(1)仅适用于字符串包含一个重复字母的情况,例如aaaaaaa
。
奖金:您的代码可以通过这种方式“压缩”:)
function firstNotRepeatingCharacters(s, d={}, r="_") {
for(let i=0; i<s.length; i++) d[s[i]]=++d[s[i]]|0;
for(let i=s.length-1; i>=0; i--) if(!d[s[i]]) r=s[i];
return r;
}
console.log(firstNotRepeatingCharacters('abacabad'));
console.log(firstNotRepeatingCharacters('abacabaabacaba'));
答案 2 :(得分:1)
实际上,这是0(1)复杂度,但仅在空间限制上。由于我们有上限。此限制可以是UTF-16,也可以是英文字母的数量。
这是开发人员提供的约束。也就是说,如果上面的代码运行了一组有限的组合,那么空间限制仅为0(1)。
一个字符串,它受实现限制为64位字符“数组”。因此,“字符串”类型的存储容量通常为2147483647(2ˆ31-1)个字符。那不是0(1)真正代表的。所以实际上这是一个0(N)的空间限制。
现在,由于时间复杂度的限制,这里的情况完全不同。在最佳情况下,它应该为0(N)+ 0(N-E)+ 0(N)。
说明: 1.第一个0(N),第一个循环遍历所有元素 2.第二个0(N)与删除有关。代码删除数组中的元素。 3. 0(N-E),第二个forEach循环最终弹出的数组,因此我们有一个常数E。
那是假设数据结构是一个数组。
Digg这里有很多东西。
TL; DR
它不是0(1)。