Algorithm 数组中连续元素的最大乘积

Algorithm 数组中连续元素的最大乘积,algorithm,Algorithm,我在现场采访时被问到这个问题。因为我没有被要求签署保密协议,所以我把它贴在这里作为答案 给定一个不包含0的实数数组,找出产生最大乘积的连续元素。该算法应在线性时间内运行 我考虑过以下方法: 使用两个数组。第一个是使用DP idea记录当前最大绝对值乘积,第二个数组记录到目前为止遇到的负元素数。最终结果应该是最大绝对值,负数的数目应该是偶数 我原以为我的方法会起作用,但在编码过程中被打断,说它不会起作用。 请告诉我上述方法中缺少了什么。您可以实现Kadane算法()的一个变体,该算法使用恒定的额外

我在现场采访时被问到这个问题。因为我没有被要求签署保密协议,所以我把它贴在这里作为答案

给定一个不包含0的实数数组,找出产生最大乘积的连续元素。该算法应在线性时间内运行

我考虑过以下方法: 使用两个数组。第一个是使用DP idea记录当前最大绝对值乘积,第二个数组记录到目前为止遇到的负元素数。最终结果应该是最大绝对值,负数的数目应该是偶数

我原以为我的方法会起作用,但在编码过程中被打断,说它不会起作用。
请告诉我上述方法中缺少了什么。

您可以实现Kadane算法()的一个变体,该算法使用恒定的额外内存和问题大小的线性(无额外数组,…)

如果只给出严格的正数:

def max_subarray_mul(A):
max\u ending\u here=max\u so\u far=1
对于A中的x:
如果x>0
max_ending_here=max(1,max_ending_here*x)
max_so_far=max(max_so_far,max_ending_此处)
返回到目前为止的最大值
我还在做负数的部分

或者更昂贵(及时)的方法如下,但这将适用于负数:

def max_subarray_mul(A):
到目前为止的最大值=1
n=长度(A)
对于1…n中的i:
x=A[i]
tmp=x
max_so_far=max(max_so_far,tmp)
对于i+1…n中的j:
tmp=tmp*A[j]
max_so_far=max(max_so_far,tmp)
返回到目前为止的最大值
它在恒定内存中运行,并且
O(n²)
time

算法确实是O(n)。迭代数组时,使用一个变量存储到目前为止找到的最大值,一个变量存储在[i]处结束的子数组的最大值,另一个变量存储在[i]处结束的最小值以处理负值

float find_maximum(float arr[], int n) {
    if (n <= 0) return NAN;

    float max_at = arr[0];  // Maximum value that ends at arr[i]
    float min_at = arr[0];  // Minimum value that ends at arr[i]
    float max_value = max_at;

    for (int i = 1; i < n; i++) {
        float prev_max_at = max_at, prev_min_at = min_at;
        max_at = max(arr[i], arr[i] * prev_min_at, arr[i] * prev_max_at);
        min_at = min(arr[i], arr[i] * prev_min_at, arr[i] * prev_max_at);
        max_value = max(max_value, max_at);
    }
    return max_value;
}
float find_最大值(float arr[],int n){

如果(n使用python符号:

  • 在O(n)中计算
    min(prod(v[0:])、prod(v[1:])、…、prod(v[-1])
    max(prod(v[0:])、prod(v[1:])、…、prod(v[-1])
  • 基于以下事实递归计算最大乘积:
    maxpro(v)=max(maxpro(v[:-1])*max(prod(v[0:]),prod(v[1:]),…,prod(v[-1])
    。这也是O(n)
代码如下:

#
n = 5
vmax = 10

#
v = nr.randint( 1, vmax, n )
v *= nr.randint( 0, 2, n ) * 2 - 1
#
print v

#
prod_res = np.zeros( ( 2, n ), int )
prod_res[ 0, 0 ] = prod_res[ 1, 0 ] = v[ 0 ]
for i in xrange( 1, n ) :
    prod_res[ 0, i ] = min( v[ i ], prod_res[ 1, i-1 ] * v[ i ], prod_res[ 0, i-1 ] * v[ i ] )
    prod_res[ 1, i ] = max( v[ i ], prod_res[ 1, i-1 ] * v[ i ], prod_res[ 0, i-1 ] * v[ i ] )
#
print prod_res

#
def maxpro_naive( v ) :
    return v[ 0 ] if ( len( v ) == 1 ) else max( maxpro_naive( v[ :-1 ] ), prod_res[ 1, len(v) -1 ] )
#
print maxpro_naive( v )

暂时忽略负数

A[i..j]
表示
A[i]*A[i+1]*…*A[j]

问题是找到
max(A[i..j])

请注意,
A[i..j]=A[0..j]/A[0..i-1]

所以如果我们计算所有x的
A[0..x]


然后,我们可以确定
max(A[i..j])=max(A[0..x])/min(A[0..y])

如果数组中没有1,那么生成的产品不应该是1。 这是我的密码:

#include<bits/stdc++.h>
using namespace std;

int max(int x, int y)
{ return (y > x)? y : x; }
int min(int x, int y)
{ return (y < x)? y : x; }
bool search(int a[],int k,int n)
{
    for(int i=0;i<n;i++)
    {
        if(a[i]==k)
        return true;
    }
    return false;
}

int maxSubArrayProduct(int a[], int size)
{
   int maxpos = 1, minneg=1, i;
   int pro_max = 1;

   for (i = 0; i < size; i++)
   {
        if(a[i]<0)
        {
            int temp=maxpos;
            maxpos=max(maxpos,minneg*a[i]);
            minneg=min(minneg,temp*a[i]);
        }
        if(a[i]==0)
        {maxpos=1;minneg=1;}
        if(a[i]>0)
        {
            maxpos=maxpos*a[i];
            minneg=min(minneg,minneg*a[i]);
        }
        if(pro_max<maxpos)
        pro_max=maxpos;
   }
   return pro_max;
}

/* Driver program to test maxSubArrayProduct */
int main()
{
   int a[] =  {-1,0,1};
   int n = sizeof(a)/sizeof(a[0]);
   int start=0,end=0;
   int max_pro = maxSubArrayProduct(a, n);
   if(max_pro==1)
   if(search(a,1,n))max_pro=1;
   else max_pro=0;
   printf("Maximum contiguous product is %d\n", max_pro);
   return 0;
}
#包括
使用名称空间std;
最大整数(整数x,整数y)
{返回(y>x)?y:x;}
最小整数(整数x,整数y)
{返回(y
import numpy as np

x = [-500,-400,200,0.1,-100,20,-10,2]

prod_seq_lists = [[x[0], x[1]]]  # Start assuming the first 2 elements have max product and save them in a list
product_result = []  # Contains the product of each list


for e in x[2:]:  # Start for loop from 3rd element
    if x[0] == 0 or x[1] == 0 or e == 0:  # Raise error if there's a 0
        raise IndexError('Found 0')

    temp_b = np.prod(prod_seq_lists[-1])  # Calculate the product of the last list in max_prod_seq
    temp_a = temp_b * e  # Multiply the new_element

    if temp_a >= temp_b:  # If last_list*new_element >= last_list
        prod_seq_lists[-1].append(e)  # Append the new_element in your last_list

        if e == x[-1]:
            product_result.append(temp_a)  # Save the product of the last list

    else:
        product_result.append(temp_b)  # Save the product of each list
        prod_seq_lists.append([e])  # Else, append append the new element in a new_list


print("Your array: ", prod_seq_lists)
print("The list with max product of consecutive elements: ", prod_seq_lists[np.argmax(product_result)])  # Get index of the maximum product and print that list
print("The max product of consecutive elements: ", max(product_result))
返回:

Your array:  [[-50, -40, 20], [0.1], [-100], [20], [-10], [90, 1000]]
The list with max product of consecutive elements:  [90, 1000]
The max product of consecutive elements:  90000

我编写了下面的代码,用于查找输入数组中相邻整数值的最大乘积,假设乘积也在int范围内 它将只迭代循环n/2次

int adjacentElementsProduct(int[] inputArray) {

    int maxProdct=inputArray[0]*inputArray[1];
//as we have already taken product of first two , start from 3rd and iterate till second last because we are checking the product of i+1 for every i
    for (int i=2; i<inputArray.length-1; i=i+2){
        if(inputArray[i-1]*inputArray[i] >inputArray[i]*inputArray[i+1]){
            if(inputArray[i-1]*inputArray[i]>maxProdct)
                maxProdct =inputArray[i-1]*inputArray[i];
        }
        else if(inputArray[i+1]*inputArray[i] > maxProdct)
            maxProdct=inputArray[i+1]*inputArray[i];



    }
//if its an even array the last element would have been covered while calculating product with second last, otherwise we would check the product for last and second last element and compare with maxProduct
    if(inputArray.length%2 !=0){
        if(maxProdct<inputArray[inputArray.length-1]*inputArray[inputArray.length-2]){
            maxProdct=inputArray[inputArray.length-1]*inputArray[inputArray.length-2];
        }
    }
    return maxProdct;

}
int邻接元素产品(int[]输入阵列){
int maxProdct=输入阵列[0]*输入阵列[1];
//因为我们已经得到了前两个的乘积,所以从第三个开始迭代到最后一个第二个,因为我们正在检查每个i的i+1的乘积
对于(inti=2;iinputArray[i]*inputArray[i+1]){
if(输入阵列[i-1]*输入阵列[i]>maxProdct)
maxProdct=输入阵列[i-1]*输入阵列[i];
}
else if(输入阵列[i+1]*输入阵列[i]>maxProdct)
maxProdct=输入阵列[i+1]*输入阵列[i];
}
//如果它是偶数数组,则在使用second last计算乘积时,最后一个元素将被覆盖,否则我们将检查最后一个和second last元素的乘积,并与maxProduct进行比较
如果(输入阵列长度%2!=0){
如果(maxProdct如果我们想在O(n)中求解,并允许对数组和O(n)额外空间进行两次遍历,我下面的代码将适用于Java中的所有+ve和-ve值

import java.util.ArrayList;
import java.util.List;

public class largestProductOfTwoNumbers {

    public static void main(String[] args) {
        int result = 0;
        int a[] = { -22, -5, 12, 6, 3, 4, 9, -11, 4, 5, 6, 8, 7, 7 };
        int max = 0;

        int curr = 0;
        List<Integer> list = new ArrayList();

        for (int i = 0; i < a.length - 1; i++) {

            curr = a[i] * a[i + 1];
            list.add(curr);

        }

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) > max) {
                max = list.get(i);
            }

        }
        System.out.println(max);
    }
} 
import java.util.ArrayList;
导入java.util.List;
公共类最大生成数{
公共静态void main(字符串[]args){
int结果=0;
INTA[]={-22,-5,12,6,3,4,9,-11,4,5,6,8,7};
int max=0;
int curr=0;
列表=新的ArrayList();
对于(int i=0;i最大值){
max=list.get(i);
}
}
系统输出打印项次(最大值);
}
} 

提示:假设你只有正数。如果你取对数(任意基数),问题会减少到什么程度对于每个数字?现在,你如何处理负数?考虑到连续元素的要求,并假设负数为奇数,你需要从两端进行尝试。谢谢。我正在尝试使用@IVlad的提示来想出一个解决方案。到目前为止,我已经发现,如果所有的数字都是正数,那么问题将减少到t获取数组中每个数字的日志(anybase),然后查找数组中连续元素的最大和。但是我没有