Arrays 是不是;查找总和小于某个数字的所有三元组“;有比O(n3)运行时更好的解决方案吗?
我在一次采访中被问到这个问题 给定一个整数数组,查找其和小于某个数的所有三元组 在一些混乱之后,我告诉采访者,最好的解决方案仍然会导致最坏的运行时O(n3),并且可能需要O(n3) 面试官公然不同意我的观点,并告诉我“你需要回到你的算法……”Arrays 是不是;查找总和小于某个数字的所有三元组“;有比O(n3)运行时更好的解决方案吗?,arrays,algorithm,Arrays,Algorithm,我在一次采访中被问到这个问题 给定一个整数数组,查找其和小于某个数的所有三元组 在一些混乱之后,我告诉采访者,最好的解决方案仍然会导致最坏的运行时O(n3),并且可能需要O(n3) 面试官公然不同意我的观点,并告诉我“你需要回到你的算法……” 我遗漏了什么吗?可能的优化是: 删除数组中大于总和的所有元素 对数组进行排序 运行O(N^2)选择a[i]+a[j],然后在[j+1,N]范围内对和-a[i]-a[j]进行二进制搜索,索引是可能的候选数量,但您应该减去j,因为它们已经被覆盖 复杂性将是O(
我遗漏了什么吗?可能的优化是:
总和的所有元素
李>
O(N^2)
选择a[i]+a[j]
,然后在[j+1,N]
范围内对和-a[i]-a[j]
进行二进制搜索,索引是可能的候选数量,但您应该减去j
,因为它们已经被覆盖复杂性将是
O(N^2 log N)
,稍好一些。可能的优化将是:
总和的所有元素
李>
O(N^2)
选择a[i]+a[j]
,然后在[j+1,N]
范围内对和-a[i]-a[j]
进行二进制搜索,索引是可能的候选数量,但您应该减去j
,因为它们已经被覆盖O(N^2 log N)
,稍好一些。O(n2)算法
- 对列表进行排序
- 对于每个元素ai,以下是计算组合数的方法:
- 二进制搜索并找到最大aj,使j
- 对列表进行排序
- 对于每个元素ai,以下是计算组合数的方法:
- 二进制搜索并找到最大aj,这样j
O(n^2)
time:- 首先,对数组进行排序李>
- 然后,使用第一个指针
在数组上循环i
- 现在,使用第二个指针
从那里向上循环,使用第三个指针j
从末端同时向下循环k
- 每当你处于一个
的情况下,你知道这同样适用于所有a[i]+a[j]+a[k]
j你可以解决这个
时间:O(n^2)
- 首先,对数组进行排序李>
- 然后,使用第一个指针
在数组上循环i
- 现在,使用第二个指针
从那里向上循环,使用第三个指针j
从末端同时向下循环k
- 无论何时,当您处于
的情况下,您都知道这一点适用于所有a[i]+a[j]+a[k]
j这是一个输出大小重要的问题示例。例如,如果数组只包含
,并且最大值设置为1,2,3,4,5,…,n
,则每个三元组都将是一个答案,您必须进行Ω(n3)运算才能将它们全部列出。另一方面,如果最大值为3n
,则最好在确认所有项目过大后在0
时间内完成 基本上,我们需要一个运行时间类似于O(n)
的函数,其中O(f(n)+t)
是输出大小,t
是输入大小 O(n2+t)算法的工作原理是跟踪三联体从超过极限过渡到低于极限的过渡点。然后它会在表面下产生所有的东西。空间是三维的,因此曲面是二维的,可以在聚合恒定时间内逐点跟踪 下面是一些python代码(未经测试!):n
这是一个输出大小很重要的问题示例。例如,如果数组只包含def findtriplets如下(项目、限制): surfaceCoords=[] s=已排序(项目) 对于范围内的i(len(s)): k=透镜(s)-1 对于范围内的j(i,len(s)) 当k>=0和s[i]+s[j]+s[k]>极限时: k-=1 如果k<0:break 附加((i,j,k)) 结果=[] 对于表面词汇中的(i,j,k): 对于范围(k+1)内的k2: 结果.追加((s[i],s[j],s[k2])) 返回结果
,并且最大值设置为1,2,3,4,5,…,n
,则每个三元组都将是一个答案,您必须进行Ω(n3)运算才能将它们全部列出。另一方面,如果最大值为3n
,则最好在确认所有项目过大后在0
时间内完成 基本上,我们需要一个运行时间类似于O(n)
的函数,其中O(f(n)+t)
是输出大小,t
是输入大小 O(n2+t)算法的工作原理是跟踪三联体从超过极限过渡到低于极限的过渡点。然后它会在表面下产生所有的东西。空间是三维的,因此曲面是二维的,可以在聚合恒定时间内逐点跟踪 下面是一些python代码(未经测试!):n
您需要输出所有三元组,还是只需要对它们进行计数?如果你需要输出它们,这绝对是O(n^3)最坏的情况,因为可能有O(n^3)这样的三元组。这是一个好的观点,也许我应该澄清我是否需要列出它们或查找数字。。我以为“发现”意味着得到所有的东西def findtriplets如下(项目、限制): surfaceCoords=[] s=已排序(项目) 对于范围内的i(len(s)): k=透镜(s)-1 对于范围内的j(i,len(s)) 当k>=0和s[i]+s[j]+s[k]>极限时: k-=1 如果k<0:break 附加((i,j,k)) 结果=[] 对于表面词汇中的(i,j,k): 对于范围(k+1)内的k2: 结果.追加((s[i],s[j],s[k2])) 返回结果
count= 0 for i = 0; i < N; i++ j = i+1 k = N-1 while j < k if A[i] + A[j] + A[k] < X count += k-j j++ else k--
- 二进制搜索并找到最大aj,这样j
- 二进制搜索并找到最大aj,使j