Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 是不是;查找总和小于某个数字的所有三元组“;有比O(n3)运行时更好的解决方案吗?_Arrays_Algorithm - Fatal编程技术网

Arrays 是不是;查找总和小于某个数字的所有三元组“;有比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(n3),并且可能需要O(n3)

面试官公然不同意我的观点,并告诉我“你需要回到你的算法……”


我遗漏了什么吗?

可能的优化是:

  • 删除数组中大于
    总和的所有元素
  • 对数组进行排序
  • 运行
    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,这样jO(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
                ,并且最大值设置为
                3n
                ,则每个三元组都将是一个答案,您必须进行Ω(n3)运算才能将它们全部列出。另一方面,如果最大值为
                0
                ,则最好在确认所有项目过大后在
                O(n)
                时间内完成

                基本上,我们需要一个运行时间类似于
                O(f(n)+t)
                的函数,其中
                t
                是输出大小,
                n
                是输入大小

                O(n2+t)算法的工作原理是跟踪三联体从超过极限过渡到低于极限的过渡点。然后它会在表面下产生所有的东西。空间是三维的,因此曲面是二维的,可以在聚合恒定时间内逐点跟踪

                下面是一些python代码(未经测试!):

                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
                ,并且最大值设置为
                3n
                ,则每个三元组都将是一个答案,您必须进行Ω(n3)运算才能将它们全部列出。另一方面,如果最大值为
                0
                ,则最好在确认所有项目过大后在
                O(n)
                时间内完成

                基本上,我们需要一个运行时间类似于
                O(f(n)+t)
                的函数,其中
                t
                是输出大小,
                n
                是输入大小

                O(n2+t)算法的工作原理是跟踪三联体从超过极限过渡到低于极限的过渡点。然后它会在表面下产生所有的东西。空间是三维的,因此曲面是二维的,可以在聚合恒定时间内逐点跟踪

                下面是一些python代码(未经测试!):

                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]))
                返回结果
                
                您需要输出所有三元组,还是只需要对它们进行计数?如果你需要输出它们,这绝对是O(n^3)最坏的情况,因为可能有O(n^3)这样的三元组。这是一个好的观点,也许我应该澄清我是否需要列出它们或查找数字。。我以为“发现”意味着得到所有的东西
                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--