Description

Given an positive integer array A and an interval. Return the number of subarrays whose sum is in the range of given interval.

Subarray is a part of origin array with continuous index.

Example

Example 1:

Input: A = [1, 2, 3, 4], start = 1, end = 3
Output: 4
Explanation: All possible subarrays: [1](sum = 1), [1, 2](sum = 3), [2](sum = 2), [3](sum = 3).

Example 2:

Input: A = [1, 2, 3, 4], start = 1, end = 100
Output: 10
Explanation: Any subarray is ok.

思路:

O(N) 的两根指针的算法

其实需要三根指针, 因为需要额外记录一下从哪个位置开始的加和已经 >= start 了.

对于每一个左端点 left, 求出对应的两个右端点 right_start, right_end. 前者表示最左边的使得 [left, right_start] 子数组的和不小于 start 的点, 而后者表示最右边的使得 [left, right_end] 子数组的和不大于 end 的点.

right_end - right_start + 1 就是以 left 为左端点的合法子数组的数量.

从左到右枚举 left, 而 right_start, right_end 随着left的增长也是只增不减的, 所以时间复杂度是 O(N)

O(NlogN) 的二分法

求出一个前缀和数组, 然后对于每一个前缀和 presum[right], 我们要求出两个点 left_start, left_end. 前者表示最左边的使得 [left_start, right] 子数组和不大于 end 的点, 后者表示最右边的使得 [left_end, right] 子数组和不小于 start 的点.

枚举 right, 我们可以在 presum[0..right] 上二分查找确定 left_start, left_end.

总结

上面两种方法是相通的, 都是对于子数组的一个端点, 确认另外一个端点的范围. 在枚举其中一个端点的过程, 另外一个端点的范围是单调的, 所以可以使用两根指针 O(N) 地完成.

可以把两根指针和二分法综合一下, 不过这样理论时间复杂度是不变的, 没有很大的必要. 以上两种方法推荐第一种, 复杂度更低.

public class Solution {
/**
* @param A: An integer array
* @param start: An integer
* @param end: An integer
* @return: the number of possible answer
*/
public int subarraySumII(int[] A, int start, int end) {
int n = A.length;
if (n == 0) {
return 0;
} int[] sum = new int[n + 1];
int i, l, r, res = 0;
sum[0] = 0;
for (i = 1; i <= n; ++i) {
sum[i] = sum[i - 1] + A[i - 1];
} l = r = 0;
for (i = 1; i <= n; ++i) {
while (l < i && sum[i] - sum[l] > end) {
++l;
} while (r < i && sum[i] - sum[r] >= start) {
++r;
} res += r - l;
} return res;
}
}

  

Subarray Sum II的更多相关文章

  1. [LintCode] Subarray Sum & Subarray Sum II

    Subarray Sum Given an integer array, find a subarray where the sum of numbers is zero. Your code sho ...

  2. Continuous Subarray Sum II(LintCode)

    Continuous Subarray Sum II   Given an circular integer array (the next element of the last element i ...

  3. [LintCode] Continuous Subarray Sum II

    Given an integer array, find a continuous rotate subarray where the sum of numbers is the biggest. Y ...

  4. Continuous Subarray Sum II

    Description Given an circular integer array (the next element of the last element is the first eleme ...

  5. LintCode "Subarray Sum II"

    Sliding window doesn't work. So it is a typical partial_sum base solution. As below. However if you ...

  6. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  7. [LeetCode] Maximum Size Subarray Sum Equals k 最大子数组之和为k

    Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If t ...

  8. [LeetCode] Minimum Size Subarray Sum 最短子数组之和

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  9. Path Sum II

    Path Sum II Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals ...

随机推荐

  1. java的线程池的使用

    1.线程池的创建 1.首先创建一个类,然后实现Runnable接口 public class ExectorTest implements Runnable {} 2.首先声明一个线程池的全局变量 p ...

  2. SPOJ Qtree系列

    Qtree1 将边权变为这条边连接的两个点中深度更深的点的点权,这样就可以变为带修改链上最大点权.直接树链剖分即可. 下面是一份C语言代码 #include<stdio.h> #inclu ...

  3. linux上文件的上传和下载

    现整理一篇linux上文件的上传和下载 第一种方式就是在windos上安装工具 如: 工具如何使用我就不赘述了,easy 第二种方式就是使用liux的命令(首先是文件上传) 上传文件(首先创建文件夹如 ...

  4. Flink WorkCount代码

    Flink-scala所需依赖 <properties> <flink.version>1.7.0</flink.version> </properties& ...

  5. Intellij IDEA最全的热键表(default keymap)

    Editing Ctrl + Space Basic code completion (the name of any class, method or variable) Ctrl + Shift ...

  6. ArcGIS加载数据中常用的File文件方法总结

    在介绍ArcGIS中各种数据的打开方法时,我们用到了许多对于File文件的操作,在此做一个常用用法的总结.例如, 介绍ArcGIS中各种数据的打开方法——mxd(地图文档) 以方法一为例:运用Load ...

  7. 一 python并发编程之多进程

    一 进程与程序 二 并发与并行 三 同步\异步和阻塞\非阻塞 四 进程的创建 五 进程的终止 六 进程的层次结构 七 进程的状态 八 进程并发的实现 一 进程与程序 什么是进程: 进程的概念:我们知道 ...

  8. 米尔电子i.MX8开发板评测

    基于 NXP 公司的i.MX8M 系列芯片的高性能开发平台 MYD-JX8MX开发板.是采用核心板(MYC-JX8MX)加底板(MYB-JX8MX)的形式,提供了 HDMI,LVDS(或 MIPI), ...

  9. v8--sort 方法 源码 (1) 插入排序法

    v8--sort方法源码中对于长度较短的数组使用的是插入排序法. 部分源码: function InsertionSort(a, from, to) { for (var i = from + 1; ...

  10. np.random模块的使用介绍

    np.random模块常用的一些方法介绍 名称 作用 numpy.random.rand(d0, d1, …, dn) 生成一个[d0, d1, …, dn]维的numpy数组,数组的元素取自[0, ...