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. 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.


这里只贴代码,解释什么的、后续更新 见原文 http://www.hrwhisper.me/leetcode-count-of-range-sum/


typedef long long LL;
struct SegmentTreeNode {
	LL L, R;
	int cnt;
	SegmentTreeNode *left, *right;
	SegmentTreeNode(LL L, LL R) :L(L), R(R), cnt(0), left(NULL), right(NULL) {}
};

class SegmentTree {
	SegmentTreeNode * root;
	SegmentTreeNode * buildTree(vector<LL> &nums, int L, int R) {
		if (L > R) return NULL;
		SegmentTreeNode * root = new SegmentTreeNode(nums[L], nums[R]);
		if (L == R) return root;
		int mid = (L + R) >> 1;
		root->left = buildTree(nums, L, mid);
		root->right = buildTree(nums, mid + 1, R);
		return root;
	}

	void update(SegmentTreeNode * root, LL val) {
		if (root && root->L <= val &&  val <= root->R) {
			root->cnt++;
			update(root->left, val);
			update(root->right, val);
		}
	}

	int sum(SegmentTreeNode * root, LL L, LL R) {
		if (!root || root->R < L ||  R < root->L ) return 0;
		if (L <= root->L  && root->R <= R) return root->cnt;
		return sum(root->left, L, R) + sum(root->right, L, R);
	}

public:
	SegmentTree(vector<LL> &nums, int L, int R) { root = buildTree(nums, L, R); }

	int sum(LL L, LL R) {
		return sum(root, L, R);
	}

	void update(LL val) {
		update(root, val);
	}
};

class Solution {
public:
	int countRangeSum(vector<int>& nums, int lower, int upper) {
		if (nums.size() == 0) return 0;
		vector<LL> sum_array (nums.size(),0);
		sum_array[0] = nums[0];
		for (int i = 1; i < sum_array.size(); i++) {
			sum_array[i] = nums[i] + sum_array[i - 1];
		}
		LL sum = sum_array[sum_array.size() - 1];
		sort(sum_array.begin(), sum_array.end());
		auto t = unique(sum_array.begin(), sum_array.end());
		SegmentTree tree(sum_array, 0, t - sum_array.begin() - 1);
		int ans = 0;
		for (int i = nums.size() - 1; i >= 0; i--) {
			tree.update(sum);
			sum -= nums[i];
			ans += tree.sum(lower + sum,upper + sum);
		}
		return ans;
	}
};



class FenwickTree(object):
    def __init__(self, n):
        self.sum_array = [0] * (n + 1)
        self.n = n

    def lowbit(self, x):
        return x & -x

    def add(self, x, val):
        while x <= self.n:
            self.sum_array[x] += val
            x += self.lowbit(x)

    def sum(self, x):
        res = 0
        while x > 0:
            res += self.sum_array[x]
            x -= self.lowbit(x)
        return res


class Solution(object):
    def countRangeSum(self, nums, lower, upper):
        """
        :type nums: List[int]
        :type lower: int
        :type upper: int
        :rtype: int
        """
        if not nums: return 0
        sum_array = []
        total = 0
        for num in nums:
            total += num
            sum_array += [total] + [total + lower - 1] + [total + upper]
        sum_array += [upper] + [lower - 1]
        index = {}
        for i, x in enumerate(sorted(set(sum_array))):
            index[x] = i + 1
 
        tree = FenwickTree(len(index))
        ans = 0
        for i in xrange(len(nums) - 1, -1, -1):
            tree.add(index[total], 1)
            total -= nums[i]
            ans += tree.sum(index.get(upper + total, 0)) - tree.sum(index.get(lower + total - 1, 0))
        return ans




本文是 leectode 327 Count of Range Sum 的题解,

更多leetcode题解见 http://www.hrwhisper.me/leetcode-algorithm-solution/

 



本博客若无特殊说明则由 hrwhisper 原创发布
转载请点名出处:细语呢喃 > leetcode Count of Range Sum
本文地址:http://www.hrwhisper.me/leetcode-count-of-range-sum/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值