[力扣系列]327.区间和的个数
代码
class Solution {
public:
int countRangeSum(vector<int>& nums, int lower, int upper) {
vector<long> sum(1, 0); // sum[i]的值是从A[0]+...+A[i]的和
int N = nums.size();
for (int i = 0; i < N; i++) {
sum.push_back(sum.back() + nums.at(i)); //更新sum中的数据
}
return merge_count(sum, 0, N + 1, lower, upper);
}
int binary_search_for_m(vector<long>& sum, long sum_i, int LOWER, int low, int high) {
//二分查找最小在[low,high-1]区间中最小的满足sum[m] - sum_i >= LOWER的下标n
int mid = (low + high) / 2;
if (low >= high - 1) {
if (sum[low] - sum_i >= LOWER) {
return low;
}
else {
return high;
}
}
if (sum[mid - 1] - sum_i >= LOWER) {
return binary_search_for_m(sum, sum_i, LOWER, low, mid);
} //如果sum[mid-1]满足条件,对mid左边的数组部分递归
else {
return binary_search_for_m(sum, sum_i, LOWER, mid, high);
}
}
int binary_search_for_n(vector<long>& sum, long sum_i, int UPPER, int low, int high) {
//二分查找最小在[low,high-1]区间中最小的满足sum[n]-sum_i>UPPER的下标n
if (low >= high - 1) {
if (sum[low] - sum_i > UPPER) {
return low;
}
else {
return high;
}
}
int mid = (low + high) / 2;
if (sum[mid - 1] - sum_i > UPPER) {
return binary_search_for_n(sum, sum_i, UPPER, low, mid);
} //如果sum[mid-1]满足条件,对mid左边的数组部分递归
else {
return binary_search_for_n(sum, sum_i, UPPER, mid, high);
}
}
int merge_count(vector<long>& sum, int low, int high, int LOWER, int UPPER) { //low和high-1分别是数组sum的最小和最大下标
int mid = (low + high) / 2;
if (mid == low)
return 0;
int count = merge_count(sum, low, mid, LOWER, UPPER) + merge_count(sum, mid, high, LOWER, UPPER);
int m_low = mid, m_high = high, n_low = mid, n_high = high;
for (int i = low; i < mid; i++) {
int m = binary_search_for_m(sum, sum[i], LOWER, m_low, m_high);
int n = binary_search_for_n(sum, sum[i], UPPER, n_low, n_high);
count += n - m;
}
sort(sum.begin() + low, sum.begin() + high); // 代数库中sort的效率为O(nlog(n)).
return count;
}
};
题解
未完待续..

浙公网安备 33010602011771号