zoukankan      html  css  js  c++  java
  • 20.11.7 leetcode327 区间和的个数

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

    题意:给一个整型的数组,求数组内有多少区间的区间和位于[lower,upper]中。

    分析:用前缀和数组来处理,这样区间(i,j)和就可以简单理解为pres[j]-pres[i]。一个比较简单的想法是将前缀和数组排序,然后从第一个当被减数做起,后面的与它差值在[lower,upper】之间的就是符合要求的,但有问题的是因为数组中存在负数,排序后可能前面的前缀和排到后面去了,会出现前面的前缀和减后面的这种无效情况。所以我们可以采用归并的思想,左半段和右半段分别排序,在做半段里面找被减数,右半段是减数。

    class Solution {
    public:
        int countRangeSumRecursive(vector<long>& sum, int lower, int upper, int left, int right) {
            if (left == right) {
                return 0;
            } else {
                int mid = (left + right) / 2;
                int n1 = countRangeSumRecursive(sum, lower, upper, left, mid);
                int n2 = countRangeSumRecursive(sum, lower, upper, mid + 1, right);
                int ret = n1 + n2;
    
                // 首先统计下标对的数量
                int i = left;
                int l = mid + 1;
                int r = mid + 1;
                while (i <= mid) {
                    while (l <= right && sum[l] - sum[i] < lower) l++;
                    while (r <= right && sum[r] - sum[i] <= upper) r++;
                    ret += (r - l);
                    i++;
                }
    
                // 随后合并两个排序数组
                vector<int> sorted(right - left + 1);
                int p1 = left, p2 = mid + 1;
                int p = 0;
                while (p1 <= mid || p2 <= right) {
                    if (p1 > mid) {
                        sorted[p++] = sum[p2++];
                    } else if (p2 > right) {
                        sorted[p++] = sum[p1++];
                    } else {
                        if (sum[p1] < sum[p2]) {
                            sorted[p++] = sum[p1++];
                        } else {
                            sorted[p++] = sum[p2++];
                        }
                    }
                }
                for (int i = 0; i < sorted.size(); i++) {
                    sum[left + i] = sorted[i];
                }
                return ret;
            }
        }
    
        int countRangeSum(vector<int>& nums, int lower, int upper) {
            long s = 0;
            vector<long> sum{0};
            for(auto& v: nums) {
                s += v;
                sum.push_back(s);
            }
            return countRangeSumRecursive(sum, lower, upper, 0, sum.size() - 1);
        }
    };
  • 相关阅读:
    Mysql定时器定时删除表数据
    Mysql中文排序规则
    Swoole学习-Swoole入门指南
    Cygwin安装swoole及错误解决
    php://input ,$_POST, $_GET和$HTTP_RAW_POST_DATA
    tp5-微信消息接收和处理
    [软件工程] 千帆竞发图的制作
    [构建之法论坛] 助教之路
    VS社区版 使用 OpenCover 获取测试代码覆盖率
    支持多编程语言的自动测试系统
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/13942183.html
Copyright © 2011-2022 走看看