Javascript 时间复杂度:立方时间下的3Sum算法?
如何利用二进制搜索来提高算法的时间复杂度 我正在为一些面试复习时间复杂度&我很难使我的算法更具时间效率。这是我对3-和问题的强力解决方案:有多少个三元组的和正好是0?背景:我没有CS学位Javascript 时间复杂度:立方时间下的3Sum算法?,javascript,algorithm,time-complexity,binary-search,Javascript,Algorithm,Time Complexity,Binary Search,如何利用二进制搜索来提高算法的时间复杂度 我正在为一些面试复习时间复杂度&我很难使我的算法更具时间效率。这是我对3-和问题的强力解决方案:有多少个三元组的和正好是0?背景:我没有CS学位 //BRUTE FORCE SOLUTION: N^3 var threeSum = function(list){ var count = 0; //checking each triple for(var i = 0; i < list.length; i++){ for(var
//BRUTE FORCE SOLUTION: N^3
var threeSum = function(list){
var count = 0;
//checking each triple
for(var i = 0; i < list.length; i++){
for(var j = i+1; j < list.length; j++){
for(var k = j+1; k < list.length; k++){
if(list[i] + list[j] + list[k] === 0){count++;}
}
}
}
return count;
};
//binary search code
var binarySearch = function(target, array){
var lo = 0;
var hi = array.length - 1;
//base case
while(lo <= hi){
var mid = Math.floor( lo + (hi - lo) / 2 );
if(target === array[mid]) return mid;
if(target < array[mid]){
hi = mid - 1;
}
if(target > array[mid]){
lo = mid + 1;
}
}
// value not found
return -1;
}
//暴力解决方案:N^3
var threeSum=函数(列表){
var计数=0;
//检查每三个
对于(变量i=0;i
我在网上复习普林斯顿大学的一门算法课程&教授指出,使用二进制搜索算法可以提高算法的效率
根据这位教授的说法,我们将:
- 对列表排序
- 对于每对数字,数组[i]&数组[j]二进制搜索-(数组[i]+数组[j])
(i,j)
,这是O(n^2)运行时k
,其中k=sum-j-i
。这是恒定时间O(1)k
是否存在,因为元组(i,j,k)
将求和为sum
。要执行此操作,请执行一个二进制搜索,这需要日志(n)时间k
将花费O(1)个时间,而不是logn
然而,我很难理解二进制搜索是如何解决这个问题的
这就是n^2 log(n)算法的工作原理:
(i,j)
,这是O(n^2)运行时k
,其中k=sum-j-i
。这是恒定时间O(1)k
是否存在,因为元组(i,j,k)
将求和为sum
。要执行此操作,请执行一个二进制搜索,这需要日志(n)时间另一种(更快的)解决方案是用哈希表替换排序部分。然后,查找值
k
将花费O(1)时间,而不是logn二进制搜索方法试图解决的问题是将立方算法(这是您的蛮力算法)的复杂性降低为~N^2 logn算法
正如其他评论者指出的那样,我们知道当以下语句:list[i]+list[j]+list[k]==0
为true
时,我们发现了一个3SUM的结果。这与说-(list[i]+list[j])==list[k]
是一样的。因此,该算法的目标是检查每个i
索引和j
索引对是否存在满足前面等式的相应k
索引。二进制搜索可以在~logn时间内找到那些k
索引。因此,总体增长顺序为~N^2 logn(外部for循环对应于N^2部分)
至于javascript的实现,我会这样做:
var threesum=函数(列表){
sort(函数(a,b){返回a-b});
控制台日志(列表);
var-cnt=0;
对于(var i=0;i,二进制搜索方法试图解决的问题是将立方算法(这是您的蛮力算法)的复杂性降低为~N^2 logn算法
正如其他评论者指出的那样,我们知道当以下语句:list[i]+list[j]+list[k]==0
为true
时,我们发现了一个3SUM结果。这与说-(list[i]+list[j])==list[k]是一样的
。因此,该算法的目标是检查每个i
索引和j
索引对是否存在满足上一等式的相应k
索引。二进制搜索可以在~logn时间内找到这些k
索引。因此,总体增长顺序为~N^2 logn(外部for循环对应于N^2部分)
至于javascript的实现,我会这样做:
var threesum=函数(列表){
sort(函数(a,b){返回a-b});
控制台日志(列表);
var-cnt=0;
对于(var i=0;i而言,算法基本上按照以下方式工作:
- 对数组进行排序(最坏情况
O(n^2)
,具体取决于排序算法)
- 生成所有数字对-取
O(n^2)
- 对于每一对
(i,j)
,可能存在k
,因此0=i+j+k
k只是-(i+j),因此我们可以在O(logn)中通过二进制搜索轻松查找。避免了i
因此,总的时间复杂度是O(n