[力扣系列]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;
	}
};

题解

未完待续..

posted @ 2021-03-10 17:05  edithlee  阅读(44)  评论(0)    收藏  举报