第一题 1480. 一维数组的动态和
前缀和模板题,建议背过
解题报告
第一步:预处理前缀和
一般的做法是声明一个用于存放预处理结果的数组sum,遍历现有的数组,使用sum[i] = sum[i-1] + nums[i]进行计算,因为有-1的操作,所以需要从1开始遍历。
倘若想知道证明的细节,可以参考英雄哥文章中内容:
第二步:将预处理的结果,结合通式进行计算
倘若要求l ~ r区间的前缀和,在预处理的背景下,就可以直接使用sum[r] - sum[l-1]来计算。
参考代码(C++版本)
class Solution { public: vector<int> runningSum(vector<int>& nums) { int sum[1010];//存放预处理的前缀和结果的数组 memset(sum,0,sizeof(sum)); vector<int> ans; int n = nums.size(); //预处理前缀和 for(int i = 1; i <= n;i++) { sum[i] = sum[i-1]+nums[i-1]; // cout << sum[i] <<' '; } //使用前缀和计算通式计算选定区间的和 for(int i = 1; i <= n;i++) ans.push_back(sum[i]-sum[0]); return ans; } };
第二题 1588. 所有奇数长度子数组的和
题目描述
解题报告
前缀和的变型题目,题目要求的是统计区间长度是奇数的前缀和。经过初始化之后,此时数组的下标已经从1开始了。
倘若想计算arr = [1,4,2,5,3]中的 [1,4,2],此时就是左端点l = 1,右端点r = 3,那么和2取余的结果就是0,用这种方式来统计奇数长度的区间。
参考代码(C++版本)
class Solution { public: int sumOddLengthSubarrays(vector<int>& arr) { int sum[110]; memset(sum,0,sizeof(sum)); int ans = 0; int n = arr.size(); //预处理 for(int i = 1; i <= n;i++) sum[i] = sum[i-1]+arr[i-1]; //统计奇数区间长度下的和 for(int l = 1; l <= n;l++) for(int r = l; r <= n;r++) { if((r-l)%2 == 0) ans += sum[r]-sum[l-1]; } return ans; } };
第三题 1442. 形成两个异或相等数组的三元组数目
题目描述
解题报告
这个题没有看懂,待会看大佬题解补上吧
参考代码(C++版本)
第四题 1094. 拼车
题目描述
解题报告
拼车应该算是常规的模拟题。
主要是判断当前时间点车上有的人和车容量的关系。
那么我们可以提前初始化处理车上现在的乘客经过上车和下车之后的人数,再去遍历所有行程中,车上的人数和车的容量是否冲突。
参考代码(C++版本)
class Solution { public: bool carPooling(vector<vector<int>>& trips, int capacity) { //前缀和都不用了吧,直接扫描吧 int cnt[1010];//cnt数组统计的是某个时间点,上车下车之后,车上有的人数 memset(cnt,0,sizeof(cnt)); int n = trips.size(); for(int i = 0; i < n;i++) { //获取当前轮的乘客 int nums = trips[i][0]; //获取上车的时间点 int _up = trips[i][1]; //获取下车的时间点 int _down = trips[i][2]; //统计当前车上,上车下车之后,车上有的人 cnt[_up] += nums; cnt[_down] -= nums; } int sum = 0; for(int i = 0;i < 1000;i++) { //获取某个时间点的乘客的数量 sum += cnt[i]; if(sum > capacity) return false; } return true; } };