蓝桥杯 云神的子数组和

原题目链接

题意

给定长度为n的整数数组,统计和等于x的连续子数组数量。

超时写法:暴力枚举(双重循环)

思路

枚举每个子数组的起点 (i),再从 (i) 向右枚举终点 (j),维护从 (i) 到 (j) 的累加和 sum

  • 每次 sum += arr[j]
  • sum == x,则答案 ans++

这样能统计所有连续子数组,但当 (n) 很大时会超时。

复杂度

  • 时间复杂度: O ( n 2 ) O(n^{2}) O(n2)

代码

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

int n, x, s = 0, e = 0, ans = 0;
int arr[100005];

int main() {
    cin >> n >> x;
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    for (int i = 0; i < n; i++) {
    int sum = 0;
        for (int j = i; j < n; j++) {
            sum += arr[j];
            if (sum == x) ans++;
        }
    }
    cout << ans;
    return 0;
}//by wqs

前缀和 + Hash 优化

思路

用前缀和思想:设当前前缀和为 sum,如果存在某个以前出现过的前缀和为 sum - x,那么从那个位置之后到当前位置的子数组和就是 (x)。

做法是用 unordered_map 统计每个前缀和出现次数:

  • 初始化 prefix_sum_unordered_map[0] = 1(表示空前缀)
  • 每读入一个数更新 sum
  • target = sum - x
  • prefix_sum_unordered_map[target] 加到答案上
  • 再把当前 sum 的计数加 1

复杂度

  • 平均时间复杂度: O ( n ) O(n) O(n)

代码

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

int n, x, s = 0, e = 0, sum = 0, ans = 0;
int arr[100005];
unordered_map<int, int> prefix_sum_unordered_map;

int main() {
	cin >> n >> x;
	prefix_sum_unordered_map[0] = 1;
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
		sum += arr[i];
		int target = sum - x;
		ans += prefix_sum_unordered_map[target];
		prefix_sum_unordered_map[sum]++;
	}
	cout << ans;
	return 0;
}//by wqs。
相关推荐
sonadorje2 小时前
矩阵的“秩”是什么?
算法·机器学习·矩阵
kklovecode2 小时前
数据结构---顺序表
c语言·开发语言·数据结构·c++·算法
sin_hielo2 小时前
leetcode 1292(二维前缀和)
数据结构·算法·leetcode
炽烈小老头2 小时前
【 每天学习一点算法 2026/01/19】位1的个数
学习·算法
Full Stack Developme2 小时前
时间轮算法
算法
Robert--cao2 小时前
ubuntu22.04使用Isaac Sim 4.5.1与Isaac Lab 2.1.0完成BeyondMimic 环境
人工智能·算法·机器人
leo__5202 小时前
基于模糊控制的MATLAB避障算法实现
算法·matlab·unity
橘颂TA2 小时前
【剑斩OFFER】算法的暴力美学——力扣 695 题:岛屿的最大面积
算法·leetcode·职场和发展
永远都不秃头的程序员(互关)2 小时前
【K-Means深度探索(七)】玩转图像!K-Means如何在像素世界中实现颜色压缩?
算法·机器学习·kmeans