一:什么是前缀和
前缀和可以简单理解为「数列的前 n项的和」,是一种重要的预处理方式,能大大降低查询的时间复杂度
说白了有点类似高中的数列,而且前缀和之差可以求出一些连续数组元素的值
一般用于解决一些连续数组的问题
二:前缀和应用----和为k的子数组
题目:
class Solution { public: int subarraySum(vector<int>& nums, int k) { //创建前缀和 int* prefix=new int[nums.size()+1]; prefix[0]=0; for(int i=0;i<nums.size();i++){ prefix[i+1]=nums[i]+prefix[i]; } //声明哈希表 unordered_map<int,int> mp;//K---prefix[i],V---次数 mp[0]=1;//prefix[0]=0; //判断过程 int res=0; for(int i=0;i<nums.size();i++){ //当前前缀和减去给出k值是否在哈希表中存在 if(mp.find(prefix[i+1]-k)!=mp.end())//找到了 res+=mp[prefix[i+1]-k];//频次累计 //更新哈希表 mp[prefix[i+1]]++; } return res; } };
这里注意:从prefix[1]去判断.这里前缀和数组是累加的,而且向前找,直接定义一个累加变量pre即可。
class Solution { public: int subarraySum(vector<int>& nums, int k) { //创建前缀和 int* prefix=new int[nums.size()+1]; int pre=0; //声明哈希表 unordered_map<int,int> mp;//K---prefix[i],V---次数 mp[0]=1;//prefix[0]=0; //判断过程 int res=0; for(int i=0;i<nums.size();i++){ //当前前缀和减去给出k值是否在哈希表中存在 pre+=nums[i]; if(mp.find(pre-k)!=mp.end())//找到了 res+=mp[pre-k];//频次累计 //更新哈希表 mp[pre]++; } return res; } };
二:求mod相同
题目:
题目涉及了同余数的知识:(a-b)modk==0等价于amod k==b mod k
class Solution { public: int subarraysDivByK(vector<int>& nums, int k) { int pre=0;//累计求前缀和变量 unordered_map<int,int> mp;//哈希表,存所有前缀和结果 mp[0]=1;//第一个元素nums[0]:视为pre[1]-pre[0] int res=0; for(int i=0;i<nums.size();i++){ pre+=nums[i]; //同余数:pre[i]mod k==pre[j]mod k int m=((pre%k)+k)%k;//+k是避免负数 if(mp.find(m)!=mp.end()){ res+=mp[m]; } mp[m]++; } return res; } };
这里的哈希表存储的余数--注意哈希表内容的k,v要因题而异
三:求奇数间隔次数
class Solution { public: int numberOfSubarrays(vector<int>& nums, int k) { int odd=0;//计算当前前缀和的奇数个数 unordered_map<int,int> mp;//key:奇数个数,次数 mp[0]=1; int res=0; for(int i=0;i<nums.size();i++){ odd+=(nums[i]%2==1)?1:0; if(mp.find(odd-k)!=mp.end()){ res+=mp[odd-k]; } mp[odd]++; } return res; } };
这里:前缀记录奇数的个数,查找表记录出现过的奇数的个数
四:左一半==右一半
题目:
class Solution { public: int pivotIndex(vector<int>& nums) { //遍历一遍元素,求出数组总和 int presum=0; for(int i=0;i<nums.size();i++){ presum+=nums[i]; } //再遍历一遍数组,求满足题意的 int leftsum=0;//下标左元素之和 for(int i=0;i<nums.size();i++){ if(leftsum==presum-nums[i]-leftsum){//右一半=全-左一半-该元素 return i; } leftsum+=nums[i]; } return -1; } };
版权声明:本文为weixin_47173597原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。