首页 > 其他分享 >区间和的个数

区间和的个数

时间:2023-04-25 22:45:16浏览次数:45  
标签:upper lower nums int 个数 vector 区间 presum

给你一个整数数组 nums 以及两个整数 lower 和 upper
求数组中,值位于范围 [lower, upper] (包含 lower 和 upper)之内的 区间和的个数

一. 前缀和+双重循环(超时)

class Solution {
public:
    int countRangeSum(vector<int>& nums, int lower, int upper) {
        int n = nums.size();
        vector<long long> presum(n+1);
        for(int i=0;i<n;i++)
            presum[i+1] = presum[i] + nums[i];
        int count = 0;//区间计数
        for(int i=0;i<n;i++){//区间起点
            if(nums[i]>=lower&&nums[i]<=upper) count++;//单个数区间
            for(int j=i+1;j<n;j++){//区间终点
                long long cursum = presum[j+1]-presum[i];
                if(cursum>=lower&&cursum<=upper) count++;
            }
        }
        return count;
    }
};

二. 前缀和+归并排序+双指针

对于有序的两子区间,可以用前缀和和双指针快速计算满足条件的个数

class Solution {
public:
    int countRangeSum(vector<int>& nums, int lower, int upper) {
        int n = nums.size();
        if(n==0) return 0;
        vector<long> presum(n+1);
        for(int i=0;i<n;i++)//计算前缀和
            presum[i+1] = presum[i] + nums[i];
        //后面只用看前缀和
        return countRange(presum,0,n,lower,upper);
    }
    int countRange(vector<long>&presum,int l,int r,int lower,int upper){
        if(l==r) return 0;//边界条件
        int mid = (l+r)/2;
        //分治归并
        return countRange(presum,l,mid,lower,upper)+
        countRange(presum,mid+1,r,lower,upper)+ 
        merge(presum,l,mid,r,lower,upper);
    }
    int merge(vector<long>&presum,int l,int m,int r,int lower,int upper){
        //对于两有序相邻子区间,计算下标对数量,有序是为了方便指针移动,减少查询
        int count = 0; 
        int i = l;//i在左区间初始指针
        int lp = m + 1;//右区间初始指针1
        int rp = m + 1;//右区间初始指针2
        while (i <= m) {//遍历左区间
            //找右区间满足条件的值,双指针
            while (lp <= r && presum[lp] - presum[i] < lower) lp++;//左闭
            while (rp <= r && presum[rp] - presum[i] <= upper) rp++;//右开
            count += (rp - lp);
            i++;
        }

        //合并有序数组
        int p1 = l; int p2=m+1; //合并区间辅助指针
        i=0;//辅助数组初始指针
        vector<long> sorted(r-l+1);//合并区间长度
        while(p1<=m&&p2<=r)
            sorted[i++] = presum[p1]<presum[p2]?presum[p1++]:presum[p2++];
        while(p1<=m) sorted[i++] = presum[p1++];
        while(p2<=r) sorted[i++] = presum[p2++];
        for(i=0;i<sorted.size();i++)
            presum[l+i] = sorted[i];
        
        return count;
    }
};

标签:upper,lower,nums,int,个数,vector,区间,presum
From: https://www.cnblogs.com/929code/p/17354180.html

相关文章

  • 贪心(区间选点)
    #include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;intn;structRange{intl;intr;booloperator<(constRange&w)const{returnr<w.r;}}range[N];intmain(){intn;cin>>n;for(inti=0;i<......
  • 代码随想录算法训练营第六天 | 242.有效的字母异位词 、349. 两个数组的交集 、 202.
    ......
  • HDU - 5649 线段树+区间二分答案 (好题)
    DZYhasasequencea[1…n].Itisapermutationofintegers1∼n.Nowhewantstoperformtwotypesofoperations:0lr:Sorta[l…r]inincreasingorder.1lr:Sorta[l…r]indecreasingorder.Afterdoingalltheoperations,hewilltellyouapositionk,andask......
  • 已知n个数的入栈序列,求一共有多少种出栈序列 (卡特兰数)
    已知\(n\)个数的入栈序列,求一共有多少种出栈序列这个经典问题有两种解法。解法一:设\(f(x)\)为\(x\)个数入栈后,再全部出栈的序列数量假设我们有\(4\)个数\(a,b,c,d\),我们来看\(a\)的出栈顺序.假如\(a\)第一个出栈,那么后面还有\(3\)个数没有出栈,因此方法数是\(f(3)\).假设\(......
  • 各个数据库的特点
     redis(频繁访问的数据,缓存在redis当中,访问速度得到提升,响应速度也得到提升) mongoDB(存储大数据量的数据,大数据量的访问性能提升) elasticsearch(复杂的搜索功能) neo4j(比较复杂的关系数据,比较直观的看到数据) ......
  • 力扣 435. 无重叠区间
    435.无重叠区间给定一个区间的集合 intervals ,其中 intervals[i]=[starti,endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。示例1:输入:intervals=[[1,2],[2,3],[3,4],[1,3]]输出:1解释:移除[1,3]后,剩下的区间没有重叠。示例2:输入:int......
  • 2022-04-22:给你两个正整数数组 nums 和 target ,两个数组长度相等。 在一次操作中,你可
    2022-04-22:给你两个正整数数组nums和target,两个数组长度相等。在一次操作中,你可以选择两个不同的下标i和j,其中0<=i,j<nums.length,并且:令nums[i]=nums[i]+2且令nums[j]=nums[j]-2。如果两个数组中每个元素出现的频率相等,我们称两个数组是相似的......
  • 剑指Offer——57.和为s的两个数字(c语言)
    title:剑指Offer57.和为s的两个数字(c语言)输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。示例1:输入:nums=[2,7,11,15],target=9输出:[2,7]或者[7,2]示例2:输入:nums=[10,26,30,31,47,60],......
  • C ++各个数据类型的输入输出
    C++中各个数据类型的输入输出主要使用iostream库和格式化输入输出函数printf、scanf等,下面是各个数据类型的输入输出方式:1.整型:使用cin和cout进行输入输出,或者使用scanf和printf进行输入输出。intn;cin>>n;cout<<n<<endl;scanf("%d",&n);printf("%d\n",n);2.浮点型:使......
  • C 语言各个数据类型的输入输出
    -1.整型(int)的输入输出: 输入: ```cintnum;printf("请输入一个整数:\n");scanf("%d",&num);//注意取地址符&``` 输出: ```cintnum=123;printf("这个数字是%d。\n",num);``` 2.浮点型(float和double)的输入输出: 输入: ```cfloatnum1;doubl......