蓝桥杯 云神的子数组和

原题目链接

题意

给定长度为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。
相关推荐
leobertlan6 小时前
痛苦系列 | DSP-03 跨越单位圆:Z变换与零极点分析
算法·程序员
蛋蛋的就会顺顺的6 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
开发小能手1237 小时前
答案daanC语言
数据结构·算法
Navigator_Z8 小时前
LeetCode //C - 1291. Sequential Digits
c语言·算法·leetcode
pride.li9 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
旺仔仔仔10 小时前
机器人项目实战(5):从单次抓取,到接收指令连续做事
算法
旺仔仔仔10 小时前
机器人项目实战(2):识别物体、提取点云,再到抓取姿态
算法
姜鱼问生10 小时前
密码明明一样,为什么 GPG 说“错的“?
后端·算法·架构
启观川11 小时前
数据结构与算法-第 3 章 常用算法-贪心算法
数据结构·笔记·python·算法·贪心算法
对空六课11 小时前
指标口径生效时间的版本查询实现
大数据·服务器·前端·算法·数据分析