返回
菜狗题解:前缀和(C++)——力扣第278场周赛第二题
后端
2023-09-19 04:08:09
在力扣第278场周赛中,第二题是一道有关前缀和的题目。题目的如下:
给你一个长度为 n 的数组 nums,它包含 0 和 1。请你找到所有满足以下条件的下标对 (i, j):
- i < j
- nums[i] = 1
- nums[j] = 1
- 在区间 [i+1, j-1] 中,nums[k] = 0
简而言之,我们要求出满足上述条件的子数组的个数。
解决这道题的方法之一是使用前缀和来计算区间中 0 和 1 的个数。前缀和是一种数据结构,它存储了数组中每个元素到当前元素的和。通过使用前缀和,我们可以快速地计算出一个区间中元素的和。
以下是解决这道题的步骤:
- 创建一个长度为 n+1 的数组 prefix,其中 prefix[i] 表示 nums[0] 到 nums[i-1] 的和。
- 遍历数组 nums,并计算出每个位置的左右前缀和。左前缀和是 prefix[i] - prefix[i-1],右前缀和是 prefix[n] - prefix[i+1]。
- 对于每个位置 i,如果 nums[i] = 1,那么我们就可以使用左右前缀和来计算出以 i 为中心满足条件的子数组的个数。具体来说,我们可以计算出以 i 为中心且左右前缀和分别为 x 和 y 的子数组的个数。这个数量是 x * y。
- 将所有满足条件的子数组的个数累加起来,即可得到最终答案。
使用上述方法,我们可以快速地解决这道题。
代码实现:
class Solution {
public:
long long countExcellentPairs(vector<int>& nums, int k) {
int n = nums.size();
vector<long long> prefix(n + 1, 0);
for (int i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
long long ans = 0;
for (int i = 0; i < n; i++) {
if (nums[i] == 1) {
int left = prefix[i] - prefix[i - 1];
int right = prefix[n] - prefix[i + 1];
ans += left * right;
}
}
return ans;
}
};
时间复杂度:O(n)。
空间复杂度:O(n)。