给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。

思路:

首先用 sum(i) 表示 nums[0]~nums[i] 的和,然后分别对于每个数 i ( 0 <= i < n ) 求出以 i 为起始位置的符合条件的区间个数。

当 sum[j] - sum[i-1] 在 [lower, upper] 之间时,证明 [i, j] 是一个合法区间。

开始以为使用二分求出sum中符合lower和upper条件的位置即可。

不过发现没有数据为正数的条件,也就是说 sum 并不是递增的,无法使用二分,那么可以考虑使用 multiset 进行维护即可。

注意数据范围 要使用 long long

代码:

class Solution {
public:
int countRangeSum(vector<int>& nums, int lower, int upper) {
int n = nums.size();
if (n == 0) return 0;
multiset<long long> mst;
long long sum = 0;
int res = 0; for (int i = 0; i < n; i++) {
mst.insert(sum);
sum += nums[i];
res += distance(mst.lower_bound(sum - upper), mst.upper_bound(sum - lower));
}
return res;
}
};

搜了下题解发现也有不依赖STL的做法,使用归并排序分治解决问题。

因为归并排序的时候,会将数组分为两部分,每部分排好序之后,再进行归并。

对于此题来说,合法区间有三种情况,一种是在左区间,一种是右区间,还有一种是横跨左右区间。

只在一个区间的情况,在递归解决子区间的时候,就已经算好了,而对于横跨的情况,既然已经排好序了,直接进行二分查找就可以了。

原地merge不能使用merge而要用 inplace_merge 我确实是第一次知道,debug好久 =。=

typedef long long ll;

class Solution {
public:
int countRangeSum(vector<int>& nums, int lower, int upper) {
int n = nums.size();
if (n == 0) return 0;
vector<ll> sum(n+1, 0);
for (int i = 0; i < n; i++) {
sum[i+1] = sum[i] + nums[i];
}
return countRangeSum(sum, lower, upper, 0, n + 1);
}
int countRangeSum(vector<ll>& sum, int lower, int upper, int left, int right) {
if (left + 1 >= right) return 0;
int res = 0;
int mid = (right + left) >> 1;
res += countRangeSum(sum, lower, upper, left, mid) + countRangeSum(sum, lower, upper, mid, right);
for (int i = left; i < mid; i++) {
res += distance(lower_bound(sum.begin() + mid, sum.begin() + right, sum[i] + lower),
upper_bound(sum.begin() + mid, sum.begin() + right, sum[i] + upper));
}
inplace_merge(sum.begin()+left, sum.begin()+mid, sum.begin()+right);
// merge(sum.begin() + left, sum.begin() + mid, sum.begin() + mid, sum.begin() + right, sum.begin() + left);
return res;
}
};

LeetCode 327. Count of Range Sum 区间和的个数的更多相关文章

  1. [LeetCode] 327. Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  2. 【算法之美】你可能想不到的归并排序的神奇应用 — leetcode 327. Count of Range Sum

    又是一道有意思的题目,Count of Range Sum.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/leetcode ...

  3. leetcode@ [327] Count of Range Sum (Binary Search)

    https://leetcode.com/problems/count-of-range-sum/ Given an integer array nums, return the number of ...

  4. 327 Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  5. LeetCode 327. Count of Range Sum

    无意看到的LeetCode新题,不算太简单,大意是给一个数组,询问多少区间和在某个[L,R]之内.首先做出前缀和,将问题转为数组中多少A[j]-A[i] (j>i)在范围内. 有一种基于归并排序 ...

  6. 327. Count of Range Sum

    /* * 327. Count of Range Sum * 2016-7-8 by Mingyang */ public int countRangeSum(int[] nums, int lowe ...

  7. [LeetCode] Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  8. 【LeetCode】327. Count of Range Sum

    题目: Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusiv ...

  9. 327. Count of Range Sum(inplace_marge)

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  10. LeetCode Count of Range Sum

    原题链接在这里:https://leetcode.com/problems/count-of-range-sum/ 题目: Given an integer array nums, return th ...

随机推荐

  1. CCStheia添加include路径

    一.在系统内找到该路径 二.复制该路径,并更改写法 C:\Users\c1519\workspace_ccstheia\OLED\user_lib 改为: C:/Users/c1519/workspa ...

  2. docker无法安装而需要的换源需求

    docker无法安装镜像而需要的换源需求: 报错信息 (超时连接) 第一步: 登录阿里云:https://www.aliyun.com/ 第二步: 进入阿里云镜像加速: 点击"控制台&quo ...

  3. 【Java】线程池配置

    先看JUC包自带的一个资源 线程池执行器: 初始化参数如下 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( corePo ...

  4. 【Mybatis】06 Session获取 & 配置参数总结

    会话获取 SqlSessionFactory 最佳的获取方式就是使用Mybatis提供的资源类加载配置文件 调用会话工厂建造者实例的建造方法注入读取流 要注意的是建造者生成了了实例就可以不需要了 这里 ...

  5. 【Node】下载安装(Linux)

    不要使用源码包安装!!!编译时间太长!! 不要使用源码包安装!!!编译时间太长!! 不要使用源码包安装!!!编译时间太长!! 使用Node源码包安装 这里使用的是源码包安装 Node官网地址:也不是官 ...

  6. 【Vue】07 Webpack Part3 Loader

    Loader是Webpack的核心概念: 除了JS文件以外我们还有CSS,图片,包括一些ES6规范的代码 或者是TypeScript各种前端类型的文件 但是最终必须统一转换成JS文件,Webpack本 ...

  7. Python报错:performance hint: av/logging.pyx:232:5: the GIL to be acquired

    参考: https://stackoverflow.com/questions/77410272/problems-installing-python-av-in-windows-11 https:/ ...

  8. 【转载】 Ubuntu 中开机自动执行脚本的两种方法

    原文地址: https://www.jianshu.com/p/6366d7070642 作者:貘鸣来源:简书 ============================================ ...

  9. php日常收获

    php 1.sprintf 用法(晚上写成blog w3cschool可查) 2.使用thinkphp getfield 方法时只查询一个字段默认返回第一条数据, 如果想要返回数组需要写成: $thi ...

  10. java中的几种锁

    一.公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁.有可能,会造成优先级反转或者饥饿 ...