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. 我瞅瞅源码系列之---drf

    我瞅瞅源码系列之---drf restful规范 从cbv到drf的视图 / 快速了解drf 视图 版本 认证 权限 节流 jwt 持续更新中...

  2. django+uWSGI+nginx的工作原理流程与部署过程

    django+uWSGI+nginx的工作原理流程与部署过程 一.前言 知识的分享,不应该只是展示出来,还应该解释这样做是为什么... 献给和我一样懵懂中不断汲取知识,进步的人们. 授人与鱼,不如授人 ...

  3. docker查看日志记录

    命令格式: $ docker logs [OPTIONS] CONTAINER Options: --details 显示更多的信息 -f, --follow 跟踪实时日志 --since strin ...

  4. 给element添加自定义图标

    element为我们提供了丰富的好用的组件,图标的样式也很多,但还是有一些常用的图标没有在官方图标库里边,比如说微信.淘宝.支付宝等等.那么如何把我们需要的图标添加到进去呢? 因为element有官方 ...

  5. 将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本)

    原文:将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本) 如果你要在 WPF 程序中使用线程池完成一个特殊的任务,那么使用 .NET 的 API Task.Run 并传入一个 L ...

  6. redis cluster slots数量 为何是16384(2的14次方)

    Redis 集群并没有使用一致性hash,而是引入了哈希槽的概念. Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分has ...

  7. 在docker容器上如何实现代码的版本管理

    之前在一台centos7的虚拟机上部署了docker并运行了三个容器给开发写代码用,写代码肯定会涉及到版本控制管理. 开始建议是开发在容器中写代码,然后通过docker commit的方式将其保存为i ...

  8. FIneUICore 版本的 AppBoxMvcCore

    http://www.51aspx.com/code/codename/64088 CORE版本的APPBOXMVC欢迎下载

  9. Gitlab创建一个项目(二)创建新用户以及分配项目

    Gitlab创建一个项目(一) 1.进入gitlab控制台 2.点击“新建用户” 3.点击“Edit”,创建初始密码 4.分配项目,首页进入项目 5.进入Members菜单 6.选择用户 7.赋予权限 ...

  10. Centos7搭建DockerRegistry

    1. 说明 以下使用系统centos7,64位,镜像为CentOS-7-x86_64-Minimal-1804,均已root用户进行操作 2. 安装Registry Docker Registry 是 ...