我尝试编写最大子序列产品程序,该程序基于最大子序列求和程序的递归解决方案(即,它将遵循相同的格式)。
到目前为止,除了那些结果应为' 0,'表示序列中没有积极的产品。对于我下面的五个序列,它适用于除最后一个之外的所有序列:
sequence1 = new int[]{-2, 5, 4, 4};
sequence2 = new int[]{6, 5, 0, -3, -5, -3, 7};
sequence3 = new int[]{0, -1, 1, 5, 0, -3, -4};
sequence4 = new int[]{0, 3, 3};
sequence5 = new int[]{0, -3, 3};
这是递归方法,其中a是序列,p1最初是[0],p2是[最后一个索引]:
public static int msp3(int[] a, int p1, int p2) {
if (p1 == p2) {
if (a[p1] != 0) {
maxprod = a[p1];
} else {
maxprod = 0;
}
} else {
int m = (p1 + p2) / 2;
int L = msp3(a, p1, m);
int R = msp3(a, m + 1, p2);
int prodlt = 1, prodrt = 1, PL = 0, PR = 0;
int checkForSplit = 0;
for (int i = m; i >= p1; i--) {
if (a[i] != 0) {
prodlt = prodlt * a[i];
if (prodlt > PL) {
PL = prodlt;
}
} else {
if (i == m) {
prodlt = 1;
checkForSplit = 1;
}
}
}
for (int i = m + 1; i <= p2; i++) {
if (a[i] != 0) {
prodrt = prodrt * a[i];
if (prodrt > PR) {
PR = prodrt;
}
} else {
if (i == m + 1) {
prodrt = 1;
checkForSplit = 1;
}
}
}
if (checkForSplit == 0) {
maxprod = max3(L, R, PL * PR);
} else {
maxprod = max3(L, R, PL);
maxprod = max(maxprod, PR);
}
}
return maxprod;
}
关于&#39; checkForSplit的说明,&#39;除非a [i] == 0,否则该值为0,并且我们正在检查当前子序列中最左侧或最右侧的索引,在这种情况下,它将设置为1.这会触发不同的&lt; max3&#39;其中PL不乘以PR,逻辑是如果PL或PR为0,则两者中的另一个可能不是,在这种情况下它们不应相乘。
正如我所说,这个算法适用于除第5个序列之外的所有序列。
有什么想法吗?
答案 0 :(得分:0)
空集的乘积为1,而不是0.因此,如果您真正解决类似问题,则产品永远不会低于1.
因此,您实际尝试解决的问题更好地描述为&#34;具有2个或更多成员的子序列的最大乘积。&#34;要解决这个问题,请尝试使用递归函数来获取序列和范围,并返回4个数字:
2元素部分和3元素部分的情况需要编码为明显的特殊情况。
对于递归步骤,最小和最大元素的逻辑是显而易见的。最小和最大产品将是一方4个数字之一的8种可能产品的最小值和最大值,而另一方则是4个号码中的一个。