Java 查找数组中3个数字的最大乘积

Java 查找数组中3个数字的最大乘积,java,arrays,algorithm,dynamic-programming,Java,Arrays,Algorithm,Dynamic Programming,给定一个整数数组,它可以包含+ve和-ve数字。我必须最大化数组中任意3个元素的乘积。元素可以是非连续的 一些例子: int[] arr = {-5, -7, 4, 2, 1, 9}; // Max Product of 3 numbers = -5 * -7 * 9 int[] arr2 = {4, 5, -19, 3}; // Max Product of 3 numbers = 4 * 5 * 3 我尝试过用动态规划来解决这个问题,但是没有得到预期的结果。它返回的结果通常涉

给定一个整数数组,它可以包含+ve和-ve数字。我必须最大化数组中任意3个元素的乘积。元素可以是非连续的

一些例子:

int[] arr = {-5, -7, 4, 2, 1, 9};  // Max Product of 3 numbers = -5 * -7 * 9
int[] arr2 = {4, 5, -19, 3};       // Max Product of 3 numbers = 4 * 5 * 3
我尝试过用动态规划来解决这个问题,但是没有得到预期的结果。它返回的结果通常涉及相同的数字在乘法中的两次。因此,对于数组-
{4,2,1,9}
,它返回-
32
,即
4*4*2

这是我的密码:

public static int maxProduct(int[] arr, int count) {
    return maxProduct(arr, 0, arr.length - 1, count);
}

private static int maxProduct(int[] arr, int fromIndex, int toIndex, int count) {

    if (count == 1) {
        return maximum(arr, fromIndex, toIndex);
    } else if (toIndex - fromIndex + 1 < count) {
        return 1;
    } else {
        return MathUtil.max(maxProduct(arr, fromIndex, toIndex - 1, count - 1) * arr[toIndex - 1], 
                            maxProduct(arr, fromIndex, toIndex - 1, count));
    }
}
public static int maxProduct(int[]arr,int count){
返回最大乘积(arr,0,arr.length-1,count);
}
私有静态int-maxProduct(int[]arr,int-fromIndex,int-toIndex,int-count){
如果(计数=1){
返回最大值(arr、从索引到索引);
}否则如果(toIndex-fromIndex+1<计数){
返回1;
}否则{
返回MathUtil.max(maxProduct(arr,fromIndex,toIndex-1,count-1)*arr[toIndex-1],
最大乘积(arr,从索引到索引-1,计数);
}
}
  • MathUtil.max(inta,intb)
    是一种提供最大值
    a
    b
    的方法
  • 我传递给
    max
    方法的两个值是:
    • <代码> Max乘积< /代码>,当我们考虑最后一个元素作为产品的一部分时。
    • <代码> Max产品<代码>,当我们不认为它是产品的一部分时。
  • 代码>计数< /代码>包含要考虑的元素数。这里是
    3
  • 对于
    count==1
    ,我们必须从数组中找到1个元素的最大值。这意味着,我们必须使用最大数组元素
  • 如果
    toIndex-fromIndex+1
    ,则表示这些索引之间的数组中没有足够的元素
我有一个直觉,第一个
if
条件是失败的原因之一。因为,它只考虑数组中的最大元素,而最大乘积也可能包含负数。但我不知道该怎么处理


我使用动态规划的原因是,我可以将此解决方案推广到任何
count
值。当然,如果有人有更好的方法,即使对于
count=3
,我也欢迎这个建议(我希望避免对数组排序,因为这至少是另一种
O(nlogn)

对于count=3,您的解决方案将有三种形式中的一种:

  • 3个最大正值(假设有3个正值)

  • 最大正值和2个最小负值(假设存在正值)

  • 三个最小负值


  • 每种情况都比使用DP容易得多。

    按升序对给定数组进行排序,您必须最大限度地利用这些情况 为了得到答案

  • 排序数组中最后3个数字的乘积
  • 排序数组中前两个数与最后一个数的乘积
  • import java.util.ArrayList;
    导入java.util.HashSet;
    导入java.util.List;
    导入java.util.Set;
    公共类ComputeMaxProduct{
    公共静态void main(字符串[]args){
    int[]arr={4,5,-19,3};
    列表超集=新的ArrayList();
    用于(int a:arr){
    超集.添加(a);
    }
    int k=3;
    int maxProduct=computeMaxProduct(超集,k);
    System.out.println(“最大乘积为:“+maxProduct”);
    }
    私有静态int computeMaxProduct(列表超集,int k){
    列表res=getsubset(超集,k);
    int-maxProduct=1;
    对于(int index=0;index最大产品){
    maxProduct=产品;
    }
    }
    退货产品;
    }
    私有静态void getsubset(列表超集、int k、int idx、Set current、列表解决方案){
    //成功停止条款
    if(当前.size()==k){
    添加(新哈希集(当前));
    返回;
    }
    //无效停止子句
    if(idx==superSet.size())返回;
    整数x=超集get(idx);
    当前。添加(x);
    //“猜测”x在子集中
    获取子集(超集,k,idx+1,当前,解决方案);
    电流。移除(x);
    //“猜测”x不在子集中
    获取子集(超集,k,idx+1,当前,解决方案);
    }
    公共静态列表getSubset(列表超集,int k){
    List res=new ArrayList();
    getSubset(超集,k,0,新HashSet(),res);
    返回res;
    }
    }
    
    公共类MaxProdOfThreeNumber{
    公共int三大成员(int[]a){
    int-topfirstpos=0;
    int-topsecpos=0;
    int-topthirdpos=0;
    int-topfirstneg=0;
    int-topsecneg=0;
    int prodneg=0;
    int-prodpos=0;
    int prodmax=0;
    布尔标志=假;
    for(int i=0;iimport java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    public class ComputeMaxProduct {
        public static void main(String[] args){
    
            int [] arr = {4, 5, -19, 3};
    
            List<Integer> superSet = new ArrayList<>();
    
            for (int a : arr ){
            superSet.add(a);
            }
    
            int k = 3;
    
            int maxProduct = computeMaxProduct(superSet, k);
            System.out.println("maximum product is : " + maxProduct);
        }
    
        private static int computeMaxProduct( List<Integer> superSet, int k ){
            List<Set<Integer>> res = getSubsets(superSet,k);
            int maxProduct = 1;
            for(int index = 0; index < res.size(); index++){
            int product = 1;
            for(Integer i : res.get(index)){
                product *= i;
            }
    
            if (product > maxProduct){
                maxProduct = product;
            }
            }
    
        return maxProduct;
        }
    
    
        private static void getSubsets(List<Integer> superSet, int k, int idx, Set<Integer> current,List<Set<Integer>> solution) {
            //successful stop clause
            if (current.size() == k) {
                solution.add(new HashSet<>(current));
                return;
            }
            //unseccessful stop clause
            if (idx == superSet.size()) return;
            Integer x = superSet.get(idx);
            current.add(x);
            //"guess" x is in the subset
            getSubsets(superSet, k, idx+1, current, solution);
            current.remove(x);
            //"guess" x is not in the subset
            getSubsets(superSet, k, idx+1, current, solution);
        }
    
        public static List<Set<Integer>> getSubsets(List<Integer> superSet, int k) {
            List<Set<Integer>> res = new ArrayList<>();
            getSubsets(superSet, k, 0, new HashSet<Integer>(), res);
            return res;
        }
    }
    
    public class MaxProdofThreenumbers {
    public int ThreeLargeNumbers(int[] a) {
    int topfirstpos = 0;
        int topsecpos = 0;
        int topthirdpos = 0;
        int topfirstneg = 0;
        int topsecneg = 0;
        int prodneg = 0;
        int prodpos = 0;
        int prodmax = 0;
        boolean flag = false;
    for (int i = 0; i < a.length; i++) {
            String num = a[i] + "";
            if (num.contains("-")) {
                String array[] = num.split("-");
                num = array[1];
                flag = true;
            } else 
                flag = false;
            if (flag) {
                if (topfirstneg < Integer.valueOf(num)) {
                    topsecneg = topfirstneg;
                    topfirstneg = Integer.valueOf(num);
                } else if (topsecneg < Integer.valueOf(num)) {
    
                    topsecneg = Integer.valueOf(num);
            }
        }
            else {
                if (topfirstpos < Integer.valueOf(num)) {
                    topsecpos = topfirstpos;
                    topfirstpos = Integer.valueOf(num);
                }
            else if (topsecpos < Integer.valueOf(num)) {
                    topthirdpos = topsecpos;
                    topsecpos = Integer.valueOf(num);
                }
                else if (topthirdpos < Integer.valueOf(num)) {
                    topthirdpos = Integer.valueOf(num);
                }
            }
        }
        prodneg = topfirstneg * topsecneg;
        prodpos = topfirstpos * topsecpos;
    
        if (prodneg > prodpos) {
            prodmax = prodneg * topfirstpos;
        } else {
            prodmax = prodpos * topthirdpos;
        }
        return prodmax;
    }
    
    public static void main(String a[]) {
        int list[] = { -29, 3, -2, -57, 8, -789, 34 };
    MaxProdofThreenumbers t = new MaxProdofThreenumbers();
    System.out.println(t.ThreeLargeNumbers(list));
    
    }
    
    package interviewProblems;
    
    import interviewProblems.exceptions.ArrayTooSmallException;
    import java.util.PriorityQueue;
    
    public class Problem5 {
    
        public static void main(String[] args) {
    
            int[] data1 = new int[]{};                                  // error
            int[] data2 = new int[]{1, 5};                              // error
            int[] data3 = new int[]{1, 4, 2, 8, 9};                     // Case: all positive --> 3-max
            int[] data4 = new int[]{10, 11, 12, -20};                   // Case: 1 negative   --> 3-max
            int[] data5 = new int[]{-5, -6, -10, 7, 8, 9};              // Case: 2+ negative  --> 3-max || 1-max 2-small
            int[] data6 = new int[]{-12, -10, -6, -4};                  // Case: all negative --> 3-max
    
            int[] data7 = new int[]{-10, -10, 1, 3, 2};
            try {
                productOfThree(data2);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
    
            try {
                System.out.println(productOfThree(data3));
                System.out.println(productOfThree(data4));
                System.out.println(productOfThree(data5));
                System.out.println(productOfThree(data6));
                System.out.println(productOfThree(data7));
            } catch (Exception e) {
                System.out.println("You should not see this line");
            }
    
        }
    
        //  O(n) time
        //  O(1) memory
        private static int productOfThree(int[] data) throws ArrayTooSmallException {
            if (data.length < 3) {
                throw new ArrayTooSmallException(3 , data.length);
            }
    
            PriorityQueue<Integer> maxNumbers = new PriorityQueue<>();                  // keep track of 3 largest numbers
            PriorityQueue<Integer> minNumbers = new PriorityQueue<>((x, y) -> y - x);   // keep track of two smallest numbers
    
            for (int i = 0; i < data.length; i++) {
                maxNumbers.add(data[i]);
                minNumbers.add(data[i]);
                if(maxNumbers.size() > 3) {
                    maxNumbers.poll();
                }
                if(minNumbers.size() > 2){
                    minNumbers.poll();
                }
            }
    
            int maxLow = maxNumbers.poll();
            int maxMed = maxNumbers.poll();
            int maxHigh = maxNumbers.poll();
    
            int minHigh = minNumbers.poll();
            int minLow = minNumbers.poll();
    
            int possibleProduct1 = maxHigh * maxMed * maxLow;
            int possibleProduct2 = maxHigh * minHigh * minLow;
    
            return Math.max(possibleProduct1, possibleProduct2);
        }
    
    //  O(n) time
    //  O(n) memory
    //    private static int productOfThree(int[] data) throws ArrayTooSmallException {
    //        if(data.length < 3) {
    //            throw new ArrayTooSmallException("Array must be at least 3 long to preform productOfThree(int[] data)");
    //        }
    //
    //        PriorityQueue<Integer> maxNumbers = new PriorityQueue<>((x , y) -> y - x);    // keep track of 3 largest numbers
    //        PriorityQueue<Integer> minNumbers = new PriorityQueue<>();                    // keep track of two smallest numbers
    //
    //        for(int i = 0; i < data.length; i++) {
    //            maxNumbers.add(data[i]);
    //            minNumbers.add(data[i]);
    //        }
    //
    //        int maxHigh = maxNumbers.poll();
    //        int maxMed = maxNumbers.poll();
    //        int maxLow = maxNumbers.poll();
    //
    //        int minLow = minNumbers.poll();
    //        int minHigh = minNumbers.poll();
    //
    //        int possibleProduct1 = maxHigh * maxMed * maxLow;
    //        int possibleProduct2 = maxHigh * minHigh * minLow;
    //
    //        return Math.max(possibleProduct1 , possibleProduct2);
    //    }
    
    }
    
    public static void main(String args[]){
    
        int array[] = {-5,-1,4,2,1,9};
        Arrays.sort(array);
    
        int length = array.length;
        System.out.println(max(array[0]*array[1]*array[length-1], 
                               array[length-1]*array[length-2]*array[length-3]));   
    }
    
    r. product of last 3 numbers in sorted array
    l. product of first two and last number in the sorted array
    
    2-1) ---- => r (answer is negative)
    2-2) ---+ => l (answer is positive)
    2-3) --++ => l (answer is positive)
    2-4) -+++ => r (answer is positive)
    2-5) ++++ => r (answer is positive)
    
    2-1) ---- => r (answer is negative)
    2-2) ---0 => l (answer is 0)
    2-3) --0+ => l (answer is positive)
    2-4) -0++ => r (answer is 0)
    2-5) 0+++ => r (answer is positive)
    
    2-1) ---0 => r (answer is 0)
    2-2) --0+ => l (answer is positive)
    2-3) -0++ => l (answer is 0)
    2-4) 0+++ => r (answer is positive)
    2-5) ++++ => r (answer is positive)
    
    -00+
    
    2-1) r (negative or 0)
    2-2) l (0 or positive)
    2-3) l (0 or positive)
    2-4) r (0 or positive)
    2-5) r (positive)
    
    u have to consider 3 cases:
    1. max 3 positive elements can be the first answer(say 10*20*70).
    2. max positive elements multiplied by 2 most negative answers is another candidate(say20*-40*-60).
    3.in case where all array elements are negative,3 elements with minimum negative magnitude is answer(-1*-2*-3 in [-1,-2,3,-4,-5]).
    
    for simplicity of question we can merge 1st and 3rd case.
    find 3 maximum elements of array, similarly find 2 minimum elements of array.
    u will get 2 candidates. Print the maximum of those candidates.
    
    C++ Code:
    #include <iostream>
    #include <limits.h>
    using namespace std;
    
    int main() 
    {
        int n;  cin>>n;     int arr[n];     for(int a=0;a<n;a++)     cin>>arr[a];
        bool flag=0;
        int max1=INT_MIN,max2=INT_MIN,max3=INT_MIN;
        int min1=INT_MAX,min2=INT_MAX;
    
        for(int a=0;a<n;a++)
        {
            if(arr[a]>max1)     {max3=max2;     max2=max1;      max1=arr[a];}
       else if(arr[a]>max2)     {max3=max2;     max2=arr[a];}
       else if(arr[a]>max3)     max3=arr[a];    flag=1;
    
    
            if(arr[a]<min1)     {min2=min1;     min1=arr[a];}
       else if(arr[a]<min2)     min2=arr[a];
        }    
    
        int prod1=INT_MIN,prod2=INT_MIN;
        if(max1>INT_MIN && max2>INT_MIN && max3>INT_MIN)    prod1=max1*max2*max3;
        if(max1>INT_MIN && min1<INT_MAX && min2<INT_MAX)    prod2=max1*min1*min2;
    
        cout<<max(prod1,prod2)<<endl;                                                
    }
    
    var arr=[-10, 3, 5, 6, -20];
    function maxTripletProduct(data)
    {
      var sortedarr=data.sort(function(a,b){
      return a-b;
    })
    console.log(sortedarr);
    
    let length=sortedarr.length;
    let product1 = sortedarr[length-3]*sortedarr[length-2]*sortedarr[length-1]
    let product2=sortedarr[0]*sortedarr[1]*sortedarr[length-1];
    if(product2>product1)
      console.log(product2);
    else
      console.log(product1);
    }
    maxTripletProduct(arr);
    
     // Here is a simple java program to find the maximum product of three numbers in  an array.
    
    import java.util.*;
    import java.lang.*;
    
    class MOHAN_BERA
    {
    public static void main(String[] args)
    {
        Scanner s = new Scanner(System.in);
            System.out.println("enter the lenth of array:");
            int num1=s.nextInt();
            int[] num2=new int[num1];
            System.out.println("enter the numbers of array:");
            for(int i=0;i<num1;i++)
            {
                num2[i]=s.nextInt();
            }
            Arrays.sort(num2);//sort the array
    
            long max1=num2[num1-1]*num2[num1-2]*num2[num1-3];//Three last numbers, can be three positive numbers
            long max2=num2[num1-1]*num2[0]*num2[1];//last numbers and first two numbers,can be first two negetive and last one positive numbers
            long max3=num2[0]*num2[1]*num2[2];//for all negetives numbers
    
            long max=max1;//max1 greatest
            if(max<max2 && max3<max2) //max2 greatest
            {
                max=max2;
            }
            else if(max<max3 && max2<max3)//max3 greatest
            {
                max=max3;
            }
            System.out.println(max);
     }
     }
    
     Arrays.sort(arr);
     int max1 = (arr[n - 1] * arr[n - 2] * arr[n - 3]);
     int max2 = (arr[0] * arr[1] * arr[n - 1]);
     System.out.println(max1 > max2 ? max1 : max2);
    
    n=len(arr1)
        for i in range(0,n):
            arr1[i]=abs(arr1[i])
        arr1.sort()
        return arr1[n-1]*arr1[n-2]*arr1[n-3]
    
    function largestProduct(ints) {
        ints.sort((a, b) => b - a);
        return ints[0] * ints[1] * ints[2];
    }
    
     public static int GetHighestProductOfThree(int[] arrayOfInts)
            {
    
                if (arrayOfInts.Length < 3)
                {
                    throw new ArgumentException("Array should be atleast 3 items", nameof(arrayOfInts));
                }
    
                int highest = Math.Max(arrayOfInts[0], arrayOfInts[1]);
                int lowest = Math.Min(arrayOfInts[0], arrayOfInts[1]);
    
                int highestProductOf2 = arrayOfInts[0] * arrayOfInts[1];
                int lowestProductOf2 = arrayOfInts[0] * arrayOfInts[1];
    
                int highestProductOf3 = arrayOfInts[0] * arrayOfInts[1] * arrayOfInts[2];
    
                for (int i = 2; i < arrayOfInts.Length; i++)
                {
                    int current = arrayOfInts[i];
                    highestProductOf3 = Math.Max(Math.Max(
                        highestProductOf3,
                        current * highestProductOf2),
                        current * lowestProductOf2);
    
                    highestProductOf2 = Math.Max(Math.Max(
                        highestProductOf2,
                        current * highest),
                        current * lowest);
    
                    lowestProductOf2 = Math.Min(Math.Min(
                        lowestProductOf2,
                        current * highest),
                        current * lowest);
    
                    highest = Math.Max(highest, current);
                    lowest = Math.Min(lowest, current);
                }
    
                return highestProductOf3;
            }
    
    def solution(A):
       if len(A) < 3:
          return 0
       A.sort()
       product = A[len(A)-1] * A[len(A)-2] * A[len(A)-3]
       if A[0] < 0 and A[1] < 0:
          if A[0] * A[1] * A[len(A)-1] > product:
             product = A[0] * A[1] * A[len(A)-1]
       return product
    
    public class FindOutProductPair {
        public static void main(String args[]) {
            int arr[]= {2,4,3,6,12,1};
    //      int arr1[]= {2,4,3,7,6,5,1};
    //      int arr1[]= {-1,-4,3,7,6,5,1};
            int arr1[]= {3,2};
    
            int max1=1,max2=1,max3=1;
            for(int i=0;i<arr1.length;i++) {
                if(max1 < arr1[i]) {
                    max3=max2;
                    max2=max1;
                    max1=arr1[i];
                }else {
                    if(max2 < arr1[i]) {
                        max3=max2;
                        max2=arr1[i];
                    }
                    else {
                        if(max3< arr1[i]) {
                            max3=arr1[i];
                        }
                    }
                }
            }
            System.out.println((max3+" "+max2+" "+max1)+" <-- "+(max3*max2*max1));
        }
    } 
    
    public final static int maxProizvedenieTrexChisel(Integer m []){
    Arrays.sort(m,(g,g1)->g-g1);
    System.out.println(Arrays.toString(m));
            int mx1=m[0]*m[1]*m[2];
            int mx2=m[m.length-1]*m[m.length-2]*m[m.length-3];
            int mx3=m[0]*m[1]*m[m.length-1];
            if(mx1>mx2&mx1>mx3)
                return mx1;
                       else if(mx2>mx1&mx2>mx3)
                               return mx2;
    
            return mx3;
    
    }
    
    int maxProduct(int[] arr) {
        int max1, max2, max3 = Integer.MIN_VALUE;
        max1 = max3;
        max2 = max3;
        int min1 = Integer.MAX_VAULE;
        int min2 = Integer.MAX_VAULE;
        for(int n : arr) {
            if (n <= min1) {            // n is smaller than all
                min2 = min1;
                min1 = n;
            } else if (n < min2) {     // n lies between min1 and min2
                min2 = n;
            }
            if (n >= max1) {            // n is greater than all
                max3 = max2;
                max2 = max1;
                max1 = n;
            } else if (n >= max2) {     // n lies betweeen max1 and max2
                max3 = max2;
                max2 = n;
            } else if (n > max3) {     // n lies betwen max2 and max3
                max3 = n;
            }
        }
    }
    
    function solution(A) {
        if(A.length<3){
            return 0;
        }
        let maxElement = Number.NEGATIVE_INFINITY;
        let idx = null;
        for(let i=0;i<A.length;i++){
            if(A[i]>maxElement){
                maxElement = A[i];
                idx = i;
            }
        }
    
            A.splice(idx,1);
            A.sort((a,b)=>b-a);
            let n = A.length;
            let positiveMax = A[0]*A[1]*maxElement;
            let negativeMax = A[n-1]*A[n-2]*maxElement;
    
        return Math.max(positiveMax,negativeMax);    
    }