后缀积的定义
后缀积(Suffix Product)是数组中从某一位置到末尾所有元素的乘积。对于一个数组 arr
,其后缀积数组 suffix
定义为:
suffix[i] = \prod_{j=i}^{n-1} arr[j]
其中 n
是数组长度,suffix[i]
表示从索引 i
到末尾所有元素的乘积。
应用场景
- 优化乘积计算:用于快速计算子数组乘积,例如结合前缀积可快速求解任意区间乘积。
- 数学问题:如统计数组中满足特定乘积条件的子序列数量。
- 算法优化:替代暴力计算,降低时间复杂度(例如从
O(n^2)
降至O(n)
)。
实现方法
方法一:正向遍历计算
从数组末尾开始逆向遍历,逐步累乘:
vector<int> calculateSuffixProduct(const vector<int>& arr) {
int n = arr.size();
vector<int> suffix(n, 1);
suffix[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; --i) {
suffix[i] = arr[i] * suffix[i + 1];
}
return suffix;
}
方法二:结合前缀积
若需同时计算前缀积和后缀积,可统一处理:
void calculateProducts(const vector<int>& arr, vector<int>& prefix, vector<int>& suffix) {
int n = arr.size();
prefix[0] = arr[0];
suffix[n - 1] = arr[n - 1];
for (int i = 1; i < n; ++i) {
prefix[i] = arr[i] * prefix[i - 1];
}
for (int i = n - 2; i >= 0; --i) {
suffix[i] = arr[i] * suffix[i + 1];
}
}
注意事项
- 零值处理:若数组包含零,后缀积可能突然归零,需根据场景特殊处理。
- 整数溢出:乘积可能超出整数范围,建议使用
long long
或取模运算。 - 空间优化:若只需后缀积,可覆盖原数组或使用单变量逆向累积。
示例问题
问题:给定数组 [2, 3, 4, 5]
,求后缀积数组。
输出:
Suffix Product: [120, 60, 20, 5]
计算过程:
suffix[3] = 5
suffix[2] = 4 * 5 = 20
suffix[1] = 3 * 20 = 60
suffix[0] = 2 * 60 = 120