求子串最大积
问题:
给定一个长度为N的整数数组, 只允许用乘法, 不能用除法, 计算任意 (N-1)个数的组合乘积中最大的一组,并写出算法的时间复杂度。
解法1.
显然这不是最好的解法。
解法2.
计算前i项乘积s[i-1]与后n-(i+1)项乘积t[i+1],,总的时间复杂度为 O(N^2)
显然这不是最好的解法。
解法3.
1. P为0
那么,数组中至少包含有一个0。假设除去一个0之外,其他N-1个数的乘积为Q,根据Q的正负性进行讨论:
Q为0
说明数组中至少有两个0,那么N-1个数的乘积只能为0,返回0;
Q为正数
返回Q,因为如果以0替换此时A(N-1)中的任一个数,P(N-1)所得到的为0,必然小于Q;
Q为负数
如果以0替换此时A(N-1)中的任一个数,所得到的P(N-1)为0,大于Q,乘积最大值为0。
根据“负负得正”的乘法性质,自然想到从N个整数中去掉一个负数,使得P(N-1)为一个正数。而要使这个正数最大,这个被去掉的负数的绝对值必须是数组中最小的。
我们只需要扫描一遍数组,把绝对值最小的负数给去掉就可以了。
类似P为负数的情况,应该去掉一个绝对值最小的正数值,这样得到的P(N-1)就是最大的。
求子串最大和:
《编程珠玑》第8章的一道题:求子串最大和:
一个具有n个浮点数的向量x,要求输出相邻子向量的最大和,如图:
程序返回值应为x[2..6]的总和,即187。
在这里直接给出最适合简单的解法:
从数组的最左边x[0]开始扫描,一直到最右端x[n-1]。记录所有遇到的最大总和子向量maxendinghere。数组的最大总和maxsofar的初始值为0。
这个程序的思想就是利用maxendinghere这个变量,它保存这结束位置为i-1的最大子向量和,赋值语句:maxendinghere = max(maxendinghere+X[i], 0);,
判断maxendinghere+X[i],:若为正值,则将maxendinghere增大到i;若为负值,将maxendinghere重新置零。
复杂度只有O(n)。
算法的思量是求累加数组
题目扩展:
查找总和最接近0的子序列?
利用累加数组temp[i],temp[i]为元素0到i的和,temp[i]与temp[j]的差,当temp[i]-temp[j]=0时,则元素i到j-1的总和为0。