【算法题】求数组中子数组的最大乘积
来源:互联网 发布:阿里云个人备案要多久 编辑:程序博客网 时间:2024/05/19 06:37
《数学之美》2.13的一道题:
给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合乘积中最大的一组,并写出算法的时间复杂度。
方法一:
最容易想到的办法是:把所有可能的(N-1)个数的组合找出来,分别计算它们的乘积,并比较大小。由于总共有N个(N-1)个数的组合,总的时间复杂度为O(N*N),但显然这不是最好的解法。
方法二:
假如去掉的元素是a[i],先计算a[0]...a[i-1]的乘积,再计算a[i+1]...a[N-1]的乘积再相乘即可,为了避免重复的计算乘积,可以先遍历一遍数组求得前i个元素的乘积存入p数组,即:p[i]=Multiply(a[0]...a[i-1])(其中1 <= i <= N,特别的p[0]为1);再遍历一遍数组求得后N-i个元素的乘积存入q数组,即:q[i]=Multiply(a[i]...a[N-1])(其中0 <= i <N,特别的P[N]为1),则去掉元素a[i]的乘积res[i]=p[i]*q[i+1],第三次遍历数组就可以求得最大的乘积。总共只需遍历数组三次,每次遍历的时间复杂度为O(N),因此总的时间复杂度为O(N)。代码如下:
#include <iostream>#include <assert.h>using namespace std;int MaxProduct(int *arr, size_t len){ assert((arr != NULL) && (len > 0)); int *p = new int[len + 1]; int *q = new int[len + 1]; //p[i] records the multiply product of arr[0] to arr[i-1], //exceptionally, p[0]=1 p[0] = 1; for (int i = 1; i <= len; i++) {p[i] = p[i-1] * arr[i-1]; } //q[i] records the multiply product of arr[i] to arr[len-1], //exceptionally, p[len]=1 q[len] = 1; for (int i = len-1; i >= 0; i--) {q[i] = q[i+1] * arr[i]; } int maxRes = 0x80000000; for (int i = 0; i < len; i++) {int nTemp = p[i] * q[i+1];if (nTemp > maxRes){ maxRes = nTemp;} } return maxRes;}int main(){ int arr[6] = {1, 4, -2, 5, -3, 3}; int res = MaxProduct(arr, 6); cout << "max product : " << res << endl; return 0;}
方法三:
该方法对数组中出现的数和乘积的规律进行了分析,该方法总共只需遍历数组两次,第一次遍历完数组后某些情况可以提前结束,例如数组中0的数目大于1,则结果直接为0,因此该方法效率比方法二要高。原理很简单,不再具体赘述,可以参考《数学之美》中的叙述。代码如下:
#include <iostream>#include <assert.h>using namespace std;int MaxProduct(int *arr, size_t len){ assert((arr != NULL) && (len > 0)); size_t cntZero = 0;//count of zeros size_t cntNega = 0;//count of negatives size_t idxMinPosi = 0;//index of min positive value size_t idxMaxNega = 0;//index of max negative value size_t idxZero = 0;//index of the only zero int minPosi = arr[0]; int maxNega = 0x80000000; for (int i=0; i<len; i++) {if (arr[i] == 0){ ++cntZero; idxZero = i;}else if (arr[i] > 0){ if (arr[i] < minPosi) {minPosi = arr[i];idxMinPosi = i; }}else{ ++cntNega; if (arr[i] > maxNega) {maxNega = arr[i];idxMaxNega = i; }} } size_t nExcepPos = 0;//the pos of exception number if (cntZero > 1)//more than 1 zero {return 0; } else if (cntZero == 1)// 1 zero {if (cntNega % 2){ return 0;}else{ nExcepPos = idxZero;} } else//no zero {if (cntNega % 2){ nExcepPos = idxMaxNega;}else{ nExcepPos = idxMinPosi;} } int maxRes = 1; for (int i=0; i<len; i++) {if (i != nExcepPos){ maxRes *= arr[i];} } return maxRes;}int main(){ int arr[6] = {1, -1, -2, 5, -3, 3}; int res = MaxProduct(arr, 6); cout << "max product : " << res << endl; return 0;}
- 【算法题】求数组中子数组的最大乘积
- 数组中子数组的最大累乘积
- 数组与矩阵---数组中子数组的最大累乘积
- 求数组中子数组的最大和
- 笔试题:求最大连续子数组的最大乘积
- 007求数组中子数组最大的和
- 求子数组的最大乘积
- 求连续子数组的最大乘积
- 求子数组的最大乘积
- 求子数组最大乘积
- 获取数组中子串乘积的最大值
- 【算法拾遗】子数组的最大乘积
- 求一个数组中连续子数组的最大乘积
- 最大子数组乘积算法
- 求二维数组中子数组和中最大的值,及子数组
- 求数组中乘积最大的子串
- 求无序数组中的三个数的最大乘积
- 求连续子数组最大乘积
- js检测只输入中文和判断手机号码
- 数据库垂直分割 ,水平分割
- 基尼系数
- 在套间之间传递原始未列集的接口指针引起的死锁
- Strust2源码序列图
- 【算法题】求数组中子数组的最大乘积
- dota宽屏
- 多线程案例学习
- lucenc setBoost增加权重值
- Cannot convert 0:0 of type class java.lang.String to class java.lang.Long
- linux proc/pid/fd 查看 fd 对应的设备
- IOS开发基础
- 数据结构演示(动画逼真)形象
- shell中的大括号和小括号