• 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);
        }
    };
  • 相关阅读:
    Java 对象的序列化和反序列化
    Java 数组元素倒序的三种方式
    Java实现字符串倒序输出的几种方法
    sql ,内连接,外连接,自然连接等各种连接
    linux上 安装软件
    打乱数组
    java集合类
    我换了新博客啦
    代理模式
    抽象工厂模式
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/13942183.html
Copyright © 2020-2023  润新知