如何在具有最大乘积的数字数组中找到三元组?

时间:2017-03-06 17:41:25

标签: algorithm complexity-theory puzzle maximize

今天我遇到了以下问题。请提供一些线索,声明如下:

给定大小为A[]的数组n。在以下限制条件下最大化A[i]*A[j]*A[k]

  • i< j< ķ
  • A [i]< A [j]< A [K]

我尝试的代码如下:

#include<iostream>
using namespace std;

int main(){
  int A[]={1,3,6,8,9};
  int max=0;
  int n=sizeof(A)/sizeof(A[0]);
  for(int i=0;i<n;i++)
      for(int j=i+1;j<n;j++)
        for(int k=j+1;k<n;k++)
        {
          if(A[i]<A[j]&&A[j]<A[k]&&max<A[i]*A[j]*A[k])
            max=A[i]*A[j]*A[k];
        }
        cout<<max;
   return 0;
}

3 个答案:

答案 0 :(得分:2)

有一种简单的O(N ^ 2)算法。这是大纲:

  1. 对于每个元素y
  2. 搜索小于xy
  3. 之前的最大元素y
  4. 搜索大于z且在y
  5. 之后的最大元素y

    步骤1是O(N),步骤2&amp; 3可以在相同的循环中完成,即O(N),总共是O(N ^ 2)

    也有O(N lg N)算法,但它更复杂:

    我们可以在O(N)中预先计算并在O(1)中查询以找到范围[l,r]中的最大值。 (最初的想法是使用细分树或任何RMQ结构,感谢@PetarPetrovic指出)

    我们还在迭代数组中的每个元素的同时构建一个set(排序列表)。伪代码如下:

    Array A = []
    Set S = {}
    Ans = 0
    
    For i = 0 to N // O(N)
      // A[i] is y
      x = binary search S, maximum element in S which is < A[i] //O(lg N)
      z = RMQ(i+1, N) // O(lg N), or O(1) if we precompute in O(N)
      if(x < A[i] && A[i] < z) Ans = Max(Ans, x*A[i]*z)
      Insert A[i] into S // O(lg N)
    //Total is O(N lg N)      
    

    我们尝试将A[i]视为中间元素y

    由于我们有一个包含i之前所有元素的有序集,我们可以使用该集二进制搜索最大有效x。之后我们将当前元素插入到此集合中。

    我们使用O(N)预先计算数组并​​在O(1)中查询以找到范围[i + 1,N-1]中的最大值。找到的号码是z

    如果(x,y,z)是有效元组并且大于当前答案,我们会更新答案。

答案 1 :(得分:1)

鉴于我&lt; j&lt; k你想用3 for循环做一些事情,那你显然可以做

for(i = 0; i < n; ++i) {
    for(j = i + 1; j < n; ++j){
         if (A[i] < A[j]) {
             for(k = j + 1; k < n; ++k){
                 if(A[j] < A[k]) {
                 /*DoSomething with i,j,k*/
                 }
            }
         }
    }
}

这主要是压痕噩梦。

答案 2 :(得分:1)

以下解决方案应为O(n ^ 2)

#include <stack>
#include <iostream>
#include <stdexcept>

template <typename T>
std::stack<T> getStack (T const * a, std::size_t dimA)
 {
   if ( nullptr == a )
      throw std::runtime_error("nullptr in getStack()");

   if ( 0U == dimA )
      throw std::runtime_error("no values in getStack()");

   T              top;
   std::stack<T>  s;
   std::size_t    pos{ 0U };

   s.push(top = a[pos]);

   do
    {
      if ( top < a[pos] )
         s.push(top = a[pos]);
    }
   while ( ++pos < dimA );

   return s;
 }


int main()
 {
   int          a[] { 34, 12, 3, 7, 29, 45 };
   std::size_t  dimA { sizeof(a)/sizeof(a[0]) };
   std::size_t  numMult { 3U };


   std::stack<int> s;

   std::size_t     pos { 0U };

   do
    {
      s = getStack(a+pos, dimA - pos);
    }
   while ( (s.size() < numMult) && (numMult <= (dimA - ++pos)) );

   if ( s.size() < numMult )
      std::cout << "there is no solution" << std::endl;
   else
    {
      int res { s.top() };

      for ( auto ui = 1U ; ui < numMult ; ++ui )
       {
         s.pop();

         res *= s.top(); 
       }

      std::cout << "the solution is " << res << std::endl;
    }

   return 0;
 }