思路:将输入数组的每个元素减去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;
}