首页 > 试题广场 >

平均数为k的最长连续子数组

[编程题]平均数为k的最长连续子数组
  • 热度指数:3371 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定n正整数组成的数组,求平均数正好等于 k 的最长连续子数组的长度。

输入描述:
第一行输入两个正整数nk,用空格隔开。
第二行输入n个正整数a_i,用来表示数组。




输出描述:
如果不存在任何一个连续子数组的平均数等于k,则输出-1。
否则输出平均数正好等于 k 的最长连续子数组的长度。

示例1

输入

5 2
1 3 2 4 1

输出

3

说明

取前三个数即可,平均数为2。
哈希表存储第一次出现的前缀和
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), k = sc.nextInt();
        long pre = 0, cur;
        Map<Long, Integer> map = new HashMap<>();
        map.put(0L, 0);
        int ans = -1;
        for (int i = 1; i <= n; i++) {
            cur = pre + sc.nextInt() - k;
            if (map.containsKey(cur)) ans = Math.max(ans, i - map.get(cur));
            else map.put(cur, i);
            pre = cur;
        }
        System.out.println(ans);
    }
}


发表于 2023-08-31 15:00:16 回复(0)
#include <bits/stdc++.h>
#include <iostream>

using namespace std;

int main(){
    int n ,k;
    cin >>n >>k;
    vector<int> a(n,0);
    for(int i = 0; i < n; i++){
        cin>>a[i];
    }

    unordered_map<long, int> ump;
    ump[0] = -1;
    int start = 0;
    long long sum = 0;
    int maxlen = -1;
    for(int i = 0; i < a.size(); i++){
        sum += a[i] - k;
        if(ump.find(sum ) != ump.end()){
            maxlen = max(maxlen, i- ump[sum]);
        }else{
            ump[sum] = i;
        }
    }
    cout<<maxlen<<endl;
    return 0;
}
c++版本的前缀和+哈希表
需要注意累加和sum需要用long long
哈希表里面存的值是索引
发表于 2023-09-01 18:31:38 回复(1)
#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;


// 平均数不好处理,每个数减k转化为计算和为0的最长子数组
int main() {
    int a, b;
    while (cin >> a >> b) { // 注意 while 处理多个 case
        vector<int> nums(a);
        int res = -1;
         long long sum = 0;
        for (int i = 0; i < a; ++i) {
            cin >> nums[i];
            nums[i] -= b;
        }
        unordered_map<long long, int> mp;
        mp[0] = -1;
        for (int i = 0; i < nums.size(); ++i) {
            sum += nums[i];
            if (mp.count(sum)) {
                res = max(res, i - mp[sum]);
            }
            if (!mp.count(sum)) {
                mp[sum] = i;
            }
        }
        cout << res;
    }
}

发表于 2023-09-02 15:15:15 回复(0)
#include <iostream>
#include<map>;
using namespace std;

int main() {
    /*
        思路:
        1.既然要求平均数为k,只需把所有元素减去k,若一些元素和为0即说明这些元素平均数为k
        2.使用map<sum,i>表示前i个位置的和
        3.遍历元素进行求和。
            当出现不存在的sum时进行记录
            当出现已存在的sum时,假设此时下标为j,记录sum下标为i
            则说明在(i+1,j)这一段所有元素的和为0,即其平均数是k,是符合要求的
        4.找出最长的子数组即可
        
    */
    long n,k;
    cin>>n>>k;

    int res = -1;
    
    map<long long,int> sumMp;
    sumMp[0] = 0;


    long long sum = 0;
    long ai;
    for(int i = 1; i <= n; i++)
    {
        cin >> ai;
        sum += ai-k;

        if(sumMp.count(sum))
        {
            res = max(res, i - sumMp[sum]);
        }
        else
        {
            sumMp[sum] = i;
        }

    }

    cout<<res;
    return 0;

}
// 64 位输出请用 printf("%lld")

发表于 2023-09-09 11:41:26 回复(3)
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, k;
        vector<long long>v(n+1,0);
        map<long long,int>mp;
        int mx=0;
        mp[0]=1;
        for(int i=1;i<=n;i++)
        {
            cin>>v[i],v[i]-=k;
            v[i]+=v[i-1];
            if(!mp.count(v[i]))mp[v[i]]=i+1;
            int l=mp[v[i]];
            mx=max(mx,i-(l==0?n:l)+1);
           // cout<<(l==0?n:l)<<" "<<i<<" "<<v[i]<<" "<<mx<<"\n";
        }
        cout<<(mx==0?-1:mx)<<"\n";
    }
}
发表于 2023-10-16 17:04:46 回复(0)
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), k = sc.nextInt(), ans = -1;
        long res = 0;
        int[] a = new int[n+5];
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }
        Map<Long, Integer> b = new HashMap<>();
        b.put(0L, 0);
        for (int i = 1; i <= n; i++) {
            res += a[i] - k;
            if (b.containsKey(res)) {
                ans = Math.max(ans, i - b.get(res));
            } else {
                b.put(res, i);
            }
        }
        System.out.print(ans);
    }
}

发表于 2024-11-26 21:51:46 回复(0)
import java.util.HashMap;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
        }
        long[] prefixSum = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            prefixSum[i] = prefixSum[i - 1] + a[i - 1];
        }

        HashMap<Long, Integer> map = new HashMap<>();
        int maxLength = -1;

        for (int i = 0; i <= n; i++) {
            long target = prefixSum[i] - (long) k * i;
            if (map.containsKey(target)) {
                int length = i - map.get(target);
                maxLength = Math.max(maxLength, length);
            }
            if (!map.containsKey(target)) {
                map.put(target, i);
            }
        }

        System.out.println(maxLength);
    }
}
发表于 2024-11-23 15:42:44 回复(0)
import java.util.*;
import java.io.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] str = bf.readLine().split(" ");
        int n = Integer.parseInt(str[0]);
        long k = Long.parseLong(str[1]);

        str = bf.readLine().split(" ");
        //多个元素的平均数为k,那么对每个元素都-k,得到的元素之和一定为0,即子数组之和为0
        //子数组之和为0,那么对应的前缀和数组sum,一定有两个下标ij,sum[i]==sum[j]
        long[] nums = new long[n];
        for(int i=0;i<n;i++){
            nums[i]=Long.parseLong(str[i])-k;
        }

        long[] sums = new long[n+1];
        Map<Long, List<Integer>> sum2Index = new HashMap<>();
        for(int i=1;i<=n;i++){
            sums[i]=sums[i-1]+nums[i-1];
            List<Integer> oldValue = sum2Index.computeIfAbsent(sums[i], e->new ArrayList<>());
            oldValue.add(i);
        }
        //System.out.println(sum2Index);

        int res =-1;
        for(Long sum : sum2Index.keySet()){
            if(sum==0){//如果前缀和为0,那么[0,i]就是一个满足条件的结果了
                int curr = Collections.max(sum2Index.get(sum));
                res=Math.max(res, curr);
                continue;
            }
            if(sum2Index.get(sum).size()>=2){
                List<Integer> list = sum2Index.get(sum);
                int min=list.get(0);
                int max = list.get(0);
                for(int i=0;i<list.size();i++){
                    min = Math.min(min, list.get(i));
                    max = Math.max(max, list.get(i));
                }
                res=Math.max(res, (max-min));
            }
        }
        System.out.println(res);


    }
}

发表于 2024-09-08 14:46:54 回复(0)
#include <iostream>
#include <map>
using namespace std;

int n,k;
long N[200050];
long cur;
map<long, long> mp;
long ans = -1;
int main()
{
    cin >> n >> k;
    mp[0] = 0;
    for (long i = 1; i <= n; i++)
    {
        cin >> N[i];
        cur = cur + N[i] - k;
        if(mp.find(cur) != mp.end()){
            ans = max(ans, i - mp[cur]);
        }else{
            mp[cur] = i;
        }
    }
    cout << ans;
    return 0;
}
发表于 2023-09-01 18:57:08 回复(0)
借鉴其他大佬思路
import sys

def findMaxLength(n, k, a):
    start = 0
    end = 0
    sum = 0
    count = 0
    maxLen = 0

    while end < n:
        sum += a[end]
        count += 1
        avg = sum / count
        if avg == k:
            maxLen = max(maxLen, count)
        while avg > k & count > 1:
            sum -= a[start]
            count -= 1
            start += 1
            avg = sum / count
            if avg == k:
                maxLen = max(maxLen, count)
        end += 1

    if maxLen > 0:
        return maxLen
    else:
        return -1

n, k = map(int, input().split())
a = list(map(int, input().split()))
print(findMaxLength(n, k, a))

发表于 2023-08-30 09:33:16 回复(0)