思路:将输入数组的每个元素减去k,即可将题目转化为求“和为0的最长连续子数组”。
使用前缀和的思想,我们维护一个变量sum。并用哈希表记录前缀和为sum的最小位置。假设前i个元素和为sum,前j个元素和也为sum,那么毫无疑问,第i+1个元素开始直到第j个元素之和必然为0。根据这个思路,我们遍历一遍数组,就得到了答案。
注意这里存在一个特殊的情况,当sum = 0的时,说明前缀和就是0,那么可以直接更新答案。
#include <iostream> #include <unordered_map> using namespace std; int main() { int n, k, a; cin >> n >> k; unordered_map<long long, int> mp; long long sum = 0; int ans = -1; for (int i = 1; i <= n; ++i) { cin >> a; sum += a - k; if(sum == 0) { ans = i; //sum = 0时直接更新答案 } else if (mp.find(sum) == mp.end()) { mp[sum] = i; } else { ans = max(ans, i - mp[sum]); } } cout << ans; }