1. 区间和的个数
给你一个整数数组 nums
以及两个整数 lower
和 upper
。求数组中,值位于范围 [lower, upper]
(包含 lower
和 upper
)之内的 区间和的个数 。
区间和 S(i, j)
表示在 nums
中,位置从 i
到 j
的元素之和,包含 i
和 j
(i
≤ j
)。
Example 1
输入:nums = [-2,5,-1], lower = -2, upper = 2
输出:3
解释:存在三个区间:[0,0]、[2,2] 和 [0,2] ,对应的区间和分别是:-2 、-1 、2 。
Example 2
输入:nums = [0], lower = 0, upper = 0
输出:1
代码
class Solution {
private:
vector<int> segTree;
void build(unsigned int n) { segTree.assign(n << 2, 0); }
void insert(int node, int start, int end, int val) {
segTree[node]++;
if (start == end) return;
int mid = start + ((end - start) >> 1);
int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
val <= mid ? insert(left_node, start, mid, val) : insert(right_node, mid + 1, end, val);
}
int query(int start, int end, int L, int R, int node) {
if (start > R || end < L) return 0;
if (L <= start && end <= R) return segTree[node];
int mid = start + ((end - start) >> 1);
int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
return query(start, mid, L, R, left_node) + query(mid + 1, end, L, R, right_node);
}
public:
int countRangeSum(vector<int> &nums, int lower, int upper) {
vector<long long> preSum(nums.size() + 1, 0);
for (int i = 0; i < nums.size(); ++i) preSum[i + 1] = preSum[i] + nums[i];
set<long long> allNumbers;
for (long long x: preSum) {
allNumbers.insert(x);
allNumbers.insert(x - lower);
allNumbers.insert(x - upper);
}
unordered_map<long long, int> values; // 利用哈希表进行离散化
int idx = 0;
for (long long x: allNumbers) {
values[x] = idx;
idx++;
}
build(values.size());
int ans = 0;
for (long long x:preSum) {
int L = values[x - upper], R = values[x - lower];
ans += query(0, values.size() - 1, L, R, 0);
insert(0, 0, values.size() - 1, values[x]);
}
return ans;
}
};
2. 矩形面积 II
我们给出了一个(轴对齐的)二维矩形列表 rectangles
。 对于
rectangle
[
i
]
=
[
x
i
1
,
y
i
1
,
x
i
2
,
y
i
2
]
\text{rectangle}[i]=[x_{i1},y_{i1},x_{i2},y_{i2}]
rectangle[i]=[xi1,yi1,xi2,yi2],
(
x
i
1
,
y
i
1
)
(x_{i1},y_{i1})
(xi1,yi1) 是该矩形 左下角 的坐标,
(
x
i
2
,
y
i
2
)
(x_{i2},y_{i2})
(xi2,yi2) 是该矩形 右上角 的坐标。
计算平面中所有 rectangles
所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次 。
返回 总面积 。因为答案可能太大,返回 1e9 + 7
的 模 。
Example 1
输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
输出:6
解释:如图所示,三个矩形覆盖了总面积为6的区域。
从(1,1)到(2,2),绿色矩形和红色矩形重叠。
从(1,0)到(2,3),三个矩形都重叠。
Example 2
输入:rectangles = [[0,0,1000000000,1000000000]]
输出:49
解释:答案是 1e18 对 (1e9 + 7) 取模的结果, 即 49 。
代码
// 不会。。。