简体   繁体   English

三重态的最大值和最小值

[英]Maximum and Minimum Value for Triplet

I have a Java computational problem in which I am given an array of integers: 我有一个Java计算问题,其中得到一个整数数组:

For example: 例如:

3 -2 -10 0 1 3 -2 -10 0 1

and I am supposed to compute what is the minimal integer and maximum triplet that can be formed from these integers. 我应该计算出可以由这些整数形成的最小整数和最大三元组。 (In this case, min=-30,max=60) (在这种情况下,最小= -30,最大= 60)

I initially thought that the maximum would always be positive and minimum would always be negative. 最初,我认为最大值始终为正,最小值始终为负。

Hence, 因此,

My initial algorithm was: 我最初的算法是:

  1. Scan the array and take out the 3 largest elements inside, store into an array. 扫描阵列并取出其中的3个最大元素,存储到阵列中。
  2. At the same time, take out the 3 smallest elements inside, store into another array. 同时,取出里面的3个最小的元素,存储到另一个数组中。

By inequalities, we can deduce the following: 通过不等式,我们可以得出以下结论:

+ve = (-)(-)(+) or (+)(+)(+) + ve =(-)(-)(+)或(+)(+)(+)

-ve = (+)(+)(-) or (-)(-)(-) -ve =(+)(+)(-)或(-)(-)(-)

Hence, I used the elements from the two arrays that I computed to try to obtain the maximal and minimal triplet. 因此,我使用我计算出的两个数组中的元素来尝试获得最大和最小三元组。 (ie In order to obtain the maximal triplet, I compared the triplet formed by the largest 3 with the triplet formed by the smallest 2 and the largest integer) (即,为了获得最大的三元组,我比较了由最大3组成的三联体与由最小2和最大整数组成的三联体)

However, I realized that if all the given integers were negative, my algorithm would be defeated because of the fact that the maximal would be negative. 但是,我意识到,如果所有给定的整数都是负数,那么我的算法就会失败,因为最大值将是负数。 (Vice-versa for minimal) (反之亦然)

I know that I can simply add more checks to solve this problem or simply just use the brute force O(N^3) solution. 我知道我可以简单地添加更多检查以解决此问题,也可以仅使用蛮力O(N ^ 3)解决方案。 But there must be a better way to solve this problem. 但是必须有更好的方法来解决这个问题。

This problem must be solved by recursion and only in O(N) time. 必须通过递归并且仅在O(N)时间内解决此问题。

I am in a fix. 我已经解决了。 Could someone please guide me? 有人可以指导我吗?

Thanks. 谢谢。

There is a O(n) solution if you find the 3 maximum and 2 minimum values in linear times. 如果在线性时间内找到3个最大值和2个最小值,则有O(n)解决方案。

But you can also use nlog(n) sorting (ie quick sort) to do that job easily. 但是您也可以使用nlog(n)排序(即快速排序)轻松完成该工作。

Then here the solution to find the maximum product triplet in C with explanations in comments - 然后在这里找到在C中找到最大乘积三元组的解决方案,并在注释中进行解释-

int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b );
}

int solution(int A[], int N) {

long product = A[0] * A[1] * A[2];
if (N == 3) {
    return product;
}

// Nlog(N)
qsort(A, N, sizeof(int), cmpfunc);

if (A[N - 3] >= 0) {
    // if there is at least 3 non-negative value
    // then take three maximum values
    product = A[N - 1] * A[N - 2] * A[N - 3];

    if (A[1] < 0) {
        // if there is at least 2 negative value
        if (product < A[N - 1] * A[0] * A[1]) {
            // then take maximum positive and two minimum negative, if that is more than 3 positive values
            product = A[N - 1] * A[0] * A[1];
        }
    }

} else if (A[N - 1] >= 0) { 
    // else if there is least 1 non-negative value
    // then take maximum positive and two minimum negative
    product = A[N - 1] * A[0] * A[1];

} else {
    // otherwise, take 3 maximum negative values
    product = A[N - 1] * A[N - 2] * A[N - 3];
}

return product;
}

First, you only have to solve one of the two problems, say find the biggest triple product. 首先,您只需要解决两个问题之一,比如找到最大的三元产品。 With this you can find the least by negating all the input values, finding the biggest triple product, and negating to find the answer. 这样,您可以通过取反所有输入值,找到最大的三元乘积和取反来找到最少的东西。

So let's focus on finding the biggest. 因此,让我们专注于寻找最大的东西。 You have it pretty well worked out. 您已经很好地解决了。 Take the maximum positive number first (if there is one). 首先取最大正数(如果有)。 Then pick either the pair of the two biggest remaining positive numbers or the two biggest (in magnitude) negative numbers, whichever pair has the largest product. 然后选择两个最大的剩余正数对或两个最大的(负数)负数对,取最大的一对。

If there are no positive numbers at all, then pick the three smallest negative numbers. 如果根本没有正数,则选择三个最小的负数。

Certainly this can all be done in O(n) time, but this is not an algorithm where recursion has a natural place. 当然,这都可以在O(n)的时间内完成,但这不是递归具有自然地位的算法。 You'd have to use trivial tail recursion to substitute for loops. 您必须使用平凡的尾递归来代替循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM