[LeetCode]Count of Range Sum

题目:Count of Range Sum

Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.
Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.

Note:
A naive algorithm of O(n2) is trivial. You MUST do better than that.

Example:
Given nums = [-2, 5, -1]lower = -2upper = 2,
Return 3.
The three ranges are : [0, 0][2, 2][0, 2] and their respective sums are: -2, -1, 2.

题意:

给定一个整数数组和一个范围,找到该数组的子集(要求子集是数组中连续的数)中满足子集元素的和在给定范围内的所有子集的个数。

分析:

正常的思路,需要找数组的不同的子集,复杂度为O(n^2)。

/**
动态规划:S[i][j]表示nums中从i到j的和
S[i][j] = S[i][j - 1] + nums[j]
**/
int LeetCode::countRangeSum(vector<int>& nums, int lower, int upper){
    int n = nums.size();
    vector<vector<int>> sum(n,vector<int>(n, 0));
    int count = 0;
    for (size_t i = 0; i < n; i++){
        sum[i][i] = nums[i];
        if (sum[i][i] >= lower && sum[i][i] <= upper)++count;
    }
    for (size_t i = 0; i < n; i++){
        for (size_t j = i + 1; j < n; j++){
            sum[i][j] = sum[i][j - 1] + nums[j];
            if (sum[i][j] >= lower && sum[i][j] <= upper)++count;
        }
    }
    return count;
}

但是,它可以在O(nlogn)的复杂度中完成。

设S(n)表示前n个元素的和,SubSet(i,j)表示数组i到j的子集的和;给定的范围是[low,up];

则简单来讲,要找满足low<=SubSet(i,j)<=up的SubSet的个数。

SubSet(i,j) = S(j) - S(i);也就是要求low<=S(j) - S(i)<=up中ij的个数。

这是可以看出必然需要一个辅助数组保存前n个元素的和;

简化要求来思考:当访问到新的元素j时,得到前j项和,则此时如果是只需求以j为终点的子集中满足题目要求的和的子集个数该怎么求呢?

只需要遍历前j-1个前n项和然后用S(j)-S(k),判断是否在范围内即可;

进一步,如果前j-1个前n项和是有序的,就只要找到第一个满足下界和最后一个满足上界的,然后他们之间包含多少个元素就有多少个满足要求的子集。

这样就要求按大小顺序来存储前n项和,而且可以使用lower_bound()和upper_bound()函数来确定范围,于是就可以想到用multiset来存储前n项和。

那么要找到所有的数组中子集满足条件的个数,就需要将上面求的每个位置的子集的数量加起来即可。

/**
一个基本的想法是使用multiset保存前i个元素的和.因为set是有序的可重复的容器.
当前位置为i时的满足给定范围的序列应该是:lower=< sum[i]-sum[j]<= upper.它对应的范围是[j,i].
所以只需要计算j的个数:使得j (0=< j< i) 满足 sum[i]-upper=< sum[j]<= sum[i]-lower.
STL提供的函数upper_bound, lower_bound能够快速找到这样的j的范围,因为set有序范围内的一定满足上面的条件.
set使用红黑树来实现,因此上面的操作时间复杂度O(logN).
所以总的时间复杂度为O(NlogN).
**/
int LeetCode::countRangeSum(vector<int>& nums, int lower, int upper){
    multiset<long long>sums;//注意使用long long防止溢出
    long long sum = 0L;
    int result = 0;
    sums.insert(0);//插入第0个和
    for (size_t i = 0; i < nums.size(); i++){
        sum += nums[i];
        result += distance(sums.lower_bound(sum - upper), sums.upper_bound(sum - lower));//找到满足sum[i]-upper=< sum[j]<= sum[i]-lower的范围
        sums.insert(sum);
    }
    return result;
}
时间: 2024-10-18 15:50:18

[LeetCode]Count of Range Sum的相关文章

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

Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive. Note:A naive algorithm of O(n2) is trivial.

327. Count of Range Sum

/* * 327. Count of Range Sum * 2016-7-8 by Mingyang */ public int countRangeSum(int[] nums, int lower, int upper) { int n = nums.length; long[] sums = new long[n + 1]; for (int i = 0; i < n; ++i) sums[i + 1] = sums[i] + nums[i]; return countWhileMerg

【LeetCode】327. Count of Range Sum

题目: Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. Range sum S(i, j) is defined as the sum of the elements in nums between indices i and  j (i ≤ j), inclusive. Note: A naive algorithm of O(n2) is tr

[email&#160;protected] [327] Count of Range Sum (Binary Search)

https://leetcode.com/problems/count-of-range-sum/ Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), incl

LeetCode 327. Count of Range Sum

无意看到的LeetCode新题,不算太简单,大意是给一个数组,询问多少区间和在某个[L,R]之内.首先做出前缀和,将问题转为数组中多少A[j]-A[i] (j>i)在范围内. 有一种基于归并排序的做法,在每次归并完左右两个子区间后,当前区间两部分分别都已经排序完毕,基于有序这一点,扫描后半段区间,对于每个A[i] (i>=mid),目标区间即为[ A[i]-R, A[i]-L ], 对于有序数组来说,求出元素落在某一区间的个数直接就是upper_bound-lower_bound,事实上,这里

leetcode笔记:Range Sum Query 2D - Immutable

一. 题目描述 Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (

LeetCode OJ:Range Sum Query 2D - Immutable(区域和2D版本)

Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). Example: Given matrix = [ [3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7

(leetcode题解)Range Sum Query - Immutable

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example: Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 Note: You may assume that the array do

leetcode笔记:Range Sum Query - Immutable

一. 题目描述 Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example: Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 二. 题目分析 给定一个数组nums,求出下标i和j之间元素