题目

链接:https://leetcode-cn.com/problems/count-of-range-sum

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

说明:
最直观的算法复杂度是 O(n^2) ,请在此基础上优化你的算法。

示例:

输入: nums = [-2,5,-1], lower = -2, upper = 2,
输出: 3
解释: 3个区间分别是: [0,0], [2,2], [0,2],它们表示的和分别为: -2, -1, 2。

归并排序

由于要求区间和因此可以想到前缀和数组,设前缀和数组为preSum
问题可以转换为 preSum[j] - preSum[i] 属于[lower, upper]
如果给定两个升序排列的数组n1,n2, 尝试找出下标对(i, j), 满足: n2[j] - n1[i] 属于[lower, upper]
由于两个数组是升序排列的所以只需要在n2中维护两个指针 l, r, 一开始都指向n2的起始位置,首先考虑n1的第一个元素,l向有移动知道找到一个元素使n2[l] - n1[0] >= lower为止,这样l右侧的元素均大于n1[0] + lower, 再移动r指针,直到n2[r] - n1[0] > upper这样r左侧的元素均小于等于n1[0] + upper,所以区间[l, r)的所有下标j都满足n2[j] - n1[i] 属于[lower, upper] 。下面继续考察n1的第二个元素,由于n1是递增的所以l, r继续向右移动。 在上述过程中对于n1的每一个下标都应记录相应区间[l, r)的大小,最终就统计得到了下标对(i, j)的数量。

class Solution {private int lower;private int upper;public int countRangeSum(int[] nums, int lower, int upper) {this.lower = lower;this.upper = upper;int n = nums.length;long[] preSum = new long[n + 1];for (int i = 0; i < n; i++) {preSum[i + 1] = preSum[i] + nums[i];}return mergeSort(preSum, 0, preSum.length - 1);}public int mergeSort(long[] sums, int lo, int hi) {if (lo >= hi) {return 0;}int mid = lo + (hi - lo) / 2;int ans = 0;ans += mergeSort(sums, lo, mid);ans += mergeSort(sums, mid +  1, hi);ans += merge(sums, lo, mid, hi);return ans;}public int merge(long[] sums, int lo, int mid, int hi) {int i = lo, l = mid + 1, r = mid + 1;int count = 0;while (i <= mid) {while (l <= hi && sums[i] + lower > sums[l]) { // l 右侧的元素都大于等于 sums[i] + lowerl++;}while (r <= hi && sums[i] + upper >= sums[r]) { // r 左侧的元素都小于等于 sums[i] + upperr++;}count+= r - l;i++;}int[] aux = new int[hi - lo + 1]; int idx = 0;int p1 = lo, p2 = mid + 1;while (p1 <= mid && p2 <= hi) {if (sums[p1] < sums[p2]) {aux[idx++] = (int) sums[p1++];} else {aux[idx++] = (int) sums[p2++];}}while (p1 <= mid) {aux[idx++] = (int) sums[p1++];}while (p2 <= hi) {aux[idx++] = (int) sums[p2++];}for (int j = lo; j <= hi; j++) {sums[j] = aux[j-lo];}return count;}
}

[leetCode]327. 区间和的个数相关推荐

  1. leetcode 327. 区间和的个数(treemap)

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

  2. LeetCode 327. 区间和的个数(multiset二分查找/归并排序)

    文章目录 1. 题目 2. 解题 2.1 动态规划超时 2.2 二分查找 2.3 归并排序 1. 题目 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 low ...

  3. 327 区间和的个数

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

  4. LeetCode 795. 区间子数组个数

    给定一个元素都是正整数的数组A ,正整数 L 以及 R (L <= R). 求连续.非空且其中最大元素满足大于等于L 小于等于R的子数组个数. 例如 : 输入: A = [2, 1, 4, 3] ...

  5. 区间子数组个数 - LeetCode 795 - 从左向右与从右向左查找

    一.问题描述 给你一个整数数组 nums 和 两个整数:left 及 right .找出 nums 中连续.非空且其中最大元素在范围 [left, right] 内的子数组,并返回满足条件的子数组的个 ...

  6. 树状数组求逆序对_区间和的个数(树状数组)

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

  7. python acm 素数个数_湘潭大学OJ-1098求区间内素数个数问题

    求区间内素数个数问题 题目描述 Description 给定两个非负整数a,b,其中0<= a,b<=1,000,000,请计算这两个数之间有多少个素数.限制:Time Limit : 1 ...

  8. zoj 2112 树状数组 套主席树 动态求区间 第k个数

    总算是把动态求区间第k个数的算法看明白了. 在主席树的基础上,如果有修改操作,则要通过套树状数组来实现任意区间求第k小的问题. 刚开始看不明白什么意思,现在有一点理解.树状数组的每个元素是一个线段树, ...

  9. [归并排序]leetcode327:区间和的个数(hard)

    题目: 题解: 思路:归并排序 1)对于区间和的快速求解需要使用前缀和,由于 a 中的元素有正有负,所以前缀和数组不是单调递增的,我们可以对前缀和数组进行归并排序,顺便计算区间和的个数,求 pre[j ...

最新文章

  1. 烂大街的Spring循环依赖该如何回答?
  2. PostgreSQL ODBC问题与探索SQLSpecialColumns
  3. mybatis显示sql语句 log4j.properties配置文件
  4. easyui 插入中间行
  5. linux rkt命令,rkt 1.13.0发布,CoreOS的容器引擎
  6. 使用RAID进行磁盘管理
  7. 赶超 Python 与 Java,JavaScript 问鼎最受欢迎的编程语言
  8. TensorFlow学习笔记之 PReLU激活函数原理和代码
  9. 中文编码之GB2312,Big5,GBK简介
  10. LSB图像隐写和峰值信噪比计算的python实现
  11. r语言如何计算t分布临界值_如何利用R语言进行meta分析—详细教程(2)
  12. 软件开发生命周期及文档
  13. Android4.0.4 framebuffer 支持32位色彩深度
  14. 报错:Unable to check if JNs are ready for formatting
  15. 混沌系统matlab程序,dynamos混沌系统的追踪控制matlab代码
  16. python快速接手别人的代码_Python 爬虫代码,网上找的别人的,但是报错,求高手指点...
  17. python微信抢红包神器_Python自动抢红包教程详解
  18. Mac技巧之更改苹果电脑开机画面的技巧
  19. 骚操作,VSCode上发布知乎
  20. MATLAB在线编辑网站及使用教程

热门文章

  1. dokuwiki学习(五)——编辑页面
  2. 「亲测有效」解决:如何禁用dl.winehq.org | kali 移除winehq源 |由于没有公钥,无法验证下列签名: NO_PUBKEY 76F1A20FF987672F
  3. 计算机描述不可用win10,win10系统查看打印机属性时描述一栏显示不可用的解决方法...
  4. 【图解】三次握手,四次挥手 —— 用心看这一篇就够了
  5. 2023计算机毕业设计题目选题经验
  6. 烽火HG6821M光猫开启telnet(202302)
  7. 红蓝对抗系列之浅谈蓝队反制红队的手法一二
  8. 认真聊聊中断(软中断)
  9. EMC设计的3大规律和3大要素
  10. 5大要点,打造企业微信个人IP