我想检查n
数组是否在JavaScript中都包含相同的整数?最有效的方法是什么?
答案 0 :(得分:1)
如果数组中只有数字-使用基本CRC算法的某些变体-每个数组的复杂度为O(n),所以它可能是最快的https://en.wikipedia.org/wiki/Cyclic_redundancy_check
类似的想法,计算总和(数组)和乘积(数组),您可以使用O(n)计算两个值。例如:
1, 5, 6, 7 ,8 sum=27, prod=1680
7, 8, 1, 5, 6 sum=27, prod=1680
但是
3, 8, 5, 5, 6 sum=27, prod=3600
注意的特殊情况是0!由于那会使产品无效,因此所有值都应+1使用。
NOTE2 请记住,CRC算法的思想是使用一个字节或dword变量作为总数,并且该变量最终会溢出。
例如对于字节:250 + 10 = 5,因为该字节在255处溢出。但是这是可以的,因为两个数组都会溢出,并且错误报告的可能性很小。我相信,只要我们努力尝试,就可以从数学上证明这是可以的。
但是,如果您懒于进行数学运算并且需要绝对确定性,则可以使用此方法快速筛选所有否定候选对象,然后仅对正候选对象进行排序和比较。仍然比仅使用sort + compare更快。
注意3: 只是意识到您使用的是JS,而JS的数字有点乱,实际上并不会因算术运算而溢出。
但是,它的确会因逻辑运算符而溢出,并且CRC算法确实使用了xor,因此效果很好。这是CRC算法: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
这是一些开源实现:https://github.com/emn178/js-crc/blob/master/src/crc.js 在表面上,vista似乎遵循该算法,但是我不确定它的质量如何,您的尽职调查也是如此!
答案 1 :(得分:1)
此解决方案避免使用sort
,将算法设为O(n²),其中n是数组的数目和长度。它具有不更改数组的附加好处,并且让我们传递包含任何类型的数组,而不仅仅是数字。它通过为每个阵列项目计算一个频率袋,然后评估它们是否都保存相同的数据来进行操作。 toBag
和bagsEqual
函数均为O(n)。这使得主要算法为arraysSame
O(n²)。使用sort
代替频率袋会使解决方案O(n²log(n))变得差强人意。
function arraysSame(...arrays) {
if(arrays.length < 2) return true;
let bag1 = toBag(arrays[0]);
for(let i = 1; i < arrays.length; i++) {
const bag2 = toBag(arrays[i]);
if(!bagsEqual(bag1, bag2)) return false;
}
return true;
}
function bagsEqual(bag1, bag2) {
if(bag1.size != bag2.size) return false;
for(const [key, value] of bag1) {
if(!bag2.has(key)) return false;
if(value != bag2.get(key)) return false;
}
return true;
}
function toBag(array) {
const bag = new Map();
for(const val of array) {
const count = bag.get(val) || 0;
bag.set(val, count + 1);
}
return bag;
}