【编程之美】子数组的最大乘积

  给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组,并写出算法的时间复杂度。

  我们把所有可能的(N-1)个数的组合找出来,分别计算它们的乘积,并比较大小。由于总共有N个(N-1)个数的组合,总的时间复杂度为O(N2),显然这不是最好的解法。

分析与解法

解法一:空间换时间  

  用s[i]表示数组的前i个元素的乘积,即s[i]=a[0]*a[1]*...*a[i-1]=s[i-1]*a[i-1],边界s[0]=1;

  用t[i]表示数组的后N-i个元素的乘积,即t[i]=a[i]*a[i+1]*...*a[N-1]=a[i]*t[i+1],边界t[N]=1;

  用p[i]表示数组除第i个元素外,其他N-1个元素的乘积,即有p[i]=s[i-1]*t[i]。

  最后求出最大的p[i],时间复杂度为O(N)。

解法二:分析法

  假设N个整数乘积为P,则:

  (1) P=0

  则数组中至少有一个0。假设除去0之后,其他N-1个数的乘积为Q。

  若Q=0,则说明数组中至少有两个0,那么N-1个数的乘积只能为0;

  若Q>0,则N-1个数的最大乘积为Q;

  若Q<0,则N-1个数的最大乘积为0。

  (2) P<0

  去掉一个负数,即可得到正数。

  要使这个正数最大,则去掉绝对值最小的负数即可。

  (3) P>0

  去掉最小的正数即可。

  需要注意的是,直接求N个整数的乘积P,可能会溢出,事实上,我们只需要知道P的正负即可,并不需要得到值。可以通过求出数组中正数、负数和0的个数来判断P的正负性。时间复杂度O(N)。

思考问题

数组乘积问题:输入一个长度为n的整数数组input,输出一个长度为n的整数数组result,满足result=input数组中除了input[i]之外所有的数的乘积(假设不会溢出)。要求:具有线性的复杂度,且不能使用除法运算符。除了result数组外,能否使用O(1)的额外空间来完成这个问题呢?

时间: 2024-10-22 19:55:40

【编程之美】子数组的最大乘积的相关文章

编程之美----子数组的最大乘积

问题:给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组,并写出算法的时间复杂度. 解法一:用一个数组保存从左边到右边前i个元素的乘积.用另一个数组保存从右边到左边N-i个元素的乘积.然后结果就为两个数组中元素对应的乘积,复杂度为o(N). 解法二:设N个数的乘积为P,对P进行分析. 1,P为0,则数组中至少包含一个0,假设除去一个0后,其它N-1个数的乘积为Q,若Q为0,则数组中至少有两个0,则返回0.若Q为正数,返回Q.若Q为负数,返回0. 2

编程之美——子数组和最大值

解法一:直接求解下标i~j的子数组和最大值:复杂度O(N^2): 代码如下: 1 #include<iostream> 2 using namespace std; 3 const int INF=1000000; 4 5 int maxSum(int arr[],int n); 6 7 int main() 8 { 9 int arr[7]={-2,5,3,-6,4,-8,6}; 10 cout<<maxSum(arr,7)<<endl; 11 return 0; 1

编程之美 子数组最大乘积

给定一个长度为N的整数数组,只允许用乘法不允许用除法,计算N-1个数组合的乘积最大的一组,并写出算法的时间复杂度. 去除第i个元素的乘积可以表示为A[0]*A[1]*…A[i-1] * A[i+1]*A[i+2]*…A[N-1] #include <iostream> #include <algorithm> using namespace std; #define MAXN 1003 long long A[MAXN]; long long s[MAXN]; long long 

【编程之美】2.13 子数组的最大乘积

题目:一个有N个数的整数数组 取其中N-1个元素的子数组 求子数组的最大乘积 不能用除法. 这道题自己没有写对,没有考虑到负数的情况,只是单纯的想去掉最小的数. 但是若有负数 -5 -4 -3 中-5 * -4 = 20更大. 需要先统计正数.负数和0的个数,再分类讨论.考察的其实就是细心和耐心. //答案解法 int getMaxProductAnswer(int * a, int alen) { int NumPositive = 0; int NumNegtive = 0; int Num

编程之美2.13 子数组的最大乘积

      这道题目是求 n-1 个数的最大乘积,即数组大小为 n,则会存在 n 个 n-1 的连续数字,那么,我们需要寻找的是最大的那一个乘积.       其实看到题目,感觉很简单,循环走两遍数组就可以得到结果,但是,那样的话,复杂度是平方量级的,如果一个数组中元素很多,那么,时间效率上是不能接受的,所以,需要重新思考问题,寻找简洁的解法.       这里,我们可以利用辅助数组的办法,把需要乘在一起的数字保存下来,单独的放到数组中,然后乘在一块就可以了,这样说起来其实不是那么容易理解,我还

编程算法 - 连续子数组的最大和 代码(C)

连续子数组的最大和 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一个整型数组, 数组里有正数也有负数. 数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值. 使用一个数保存当前和, 如果当前和为小于0,  则替换新值, 否则, 递加, 使用一个数保存临时最大值. 代码: /* * main.cpp * * Created on: 2014年6月29日 * Author: wang */ #include <stdio

子数组的最大乘积

这个题目的意思是在一个含有N个数字的数组中,找出N-1个数字,使得这N-1个数字的乘积最大,不允许使用除法. 一开始看这个题的感觉可能是很简单,我只要找出这个数中最小的值,那么剩余的N-1个数的乘积一定是最大的. 但是这就忽略了一个情况,就是存在负数的情况.题目中并没有说是个正数的数组.因此在拿到一道题目时,一定要尽可能的想清楚题目的各个方面. 但是我们依然可以利用上面的这个思路进行查找.首先遍历一遍数组,记录负值绝对值最大和最小的点,0的个数,正数的个数和负数的个数.完成遍历之后,就可以根据以

[经典面试题]子数组的最大乘积

题目 给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合乘积中的最大的一组,并写出算法的时间复杂度. 思路一 穷举法 我们把所有可能的(N-1)个数的组合找出来,分别计算它们的乘积,并比较大小.由于总共有N个(N-1)个数的组合,总的时间复杂度为O(N^2),但显然这不是最好的思路. 思路二 空间换时间 计算(N-1)个数的组合乘积,假设第i个(0<=i<=N-1)元素被排除在乘积之外(如下图). 设num[]为初试数组 Left[i]表示前i个元素(包括第i个

2.13 子数组的最大乘积

题目: 给定一个长度为N的整形数组,只允许用乘法,不能用除法.计算任意N-1个数的组合中乘积最大的一组. 方法一: #include <iostream> #define MAXN 10000 using namespace std; int n, a[MAXN], s[MAXN], t[MAXN], p[MAXN]; //s[i]表示数组前i个元素的乘积 //t[i]表示数组后N-i个元素的乘积 //p[i] = s[i-1] * t[i+1]; //p[i]表示数组除第I个元素外,其他N-

【LeetCode】Maximum Product Subarray 求连续子数组使其乘积最大

Add Date 2014-09-23 Maximum Product Subarray Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4],the contiguous subarray [2,3] has the largest product =