如何解决使用JavaScript中的filter在两个未排序的数组中找到交集的大O 方法1 方法2 方法3
我刚刚开始学习Big O表示法,并且我试图了解具有不同功能的Big O,以了解哪个更好。
我正在努力为以下代码计算时空复杂度。
function findCommonElem(arr1,arr2) {
let result = arr1.filter(x => arr2.includes(x));
console.log(result);
}
findCommonElem(arr1,arr2);
据我了解,像filter()
这样的常见数组方法通常具有O(n)
的大O,因此在这种情况下,取决于每个数组的长度,它的值为O(m+n)
。但是,我可能是超级错误。
有人可以解释吗?非常感谢!
奖金问题:与对数组进行排序然后对相同的函数使用while循环相比,哪个被认为是“更好”的?
解决方法
以上函数的时间复杂度为O(M * N)
。
但是,您可以使此解决方案更有效吗?是。您可以将其减少为O(M + N)
。
TLDR-使用哈希表实现线性时间复杂度O(M + N)
让我们看看。
方法1
检查数组1的每个元素与数组2的每个元素。(这是您正在使用的方法。)
function findCommonElem(arr1,arr2) {
return arr1.filter(x => arr2.includes(x));
}
const arr1 = [1,2,3,4,5,6,7,8,9,10];
const arr2 = [2,10,12,14,16,20];
console.log(findCommonElem(arr1,arr2)); // [2,10];
-
时间复杂度=
O(M * N)
- 在最坏的情况下,将使用数组2的每个元素检查数组1中的每个元素。所以是M * N。
-
空间兼容性=
O(M)
或O(N)
- 最多,任一数组中的所有元素都可能在交点内。
方法2
使用hash map线性化嵌套循环。首先,使用数组1元素填充哈希图。然后使用地图检查数组2以找到交点。
function findCommonElem(arr1,arr2) {
const map = new Map();
arr1.forEach(item => map.set(item,true));
return arr2.filter(item => map.has(item));
}
const arr1 = [1,10];
上面的函数返回相同的输出。但这是不同的-嵌套循环被简化为数组的两个线性循环。这意味着两个数组仅被遍历一次。
-
时间复杂度=
O(M + N)
- 数组1被遍历一次(M个元素)。
- 数组2被遍历一次(N个元素)。
- 检查地图是否包含带有
map.has()
的元素会花费固定的时间O(1)
。 - 总运行时间= M + N
-
空间兼容性=
O(M)
或O(N)
- 这里的空间复杂度仍然相同,因为新哈希映射所需的空间是
O(M)
或O(N)
。我们的中间数组采用O(M)
或O(N)
。还是一样。
- 这里的空间复杂度仍然相同,因为新哈希映射所需的空间是
奖金:对哈希图如何在内部工作不了解多少?观看this。
方法3
使用set代替map。设置的数据结构最适合此用例,因为您不需要方法2中的映射值(true
值)。
function findCommonElem(arr1,arr2) {
const set = new Set(arr1);
return arr2.filter(item => set.has(item));
}
const arr1 = [1,10];
这占用的空间相对较小,但TC和SC的算法复杂度仍然相同。
- 时间复杂度=
O(M + N)
- 空间兼容性=
O(M)
或O(N)
感谢Nick Parsons指出了这一点。
,假设arr1.length
为n,arr2.length
为m。
因此filter
函数将运行您为arr1
中的每个项目编写的lambda函数。 lambda函数检查某项是否在arr2
中,在最坏的情况下,如果找不到该项,则该函数会在所有数组上运行m次。
因此arr1.filter(x => arr2.includes(x))
以最坏的情况O(n * m)运行。
对于空间复杂度,filter
函数创建一个新数组,在最坏的情况下,数组的大小与原始数组一样大,因此空间复杂度为O(n)
正如正确提到的,这里的大O等于O(n*m)
,这是对此的解释:
-
arr1.filter
的复杂度为O(n) -
arr2.includes
的复杂度也是O(n)
但是,对于.filter中的每次迭代,您都会在每次arr2.includes时执行,这导致O(n) * O(n) = O(n * m)
如果将例如arr2替换为JS Set,则可以提高性能。 JS Set。的复杂度为O(1)
,因此使用Set代替arr2应该可以帮助您实现O(n)
的复杂度。
我相信我无法回答排序问题,因为我不清楚您的意思。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。