327. Count of Range Sum(Divide and Conquer)

来源:互联网 发布:cms监控客户端下载 编辑:程序博客网 时间:2024/05/27 14:11

题目:

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.


翻译:

给定一个整数数组nums,返回位于[lower,upper](含)的范围和的个数。
范围和S(i,j)被定义为索引i和j(i≤j)之间的num中的元素的总和,包括j和j。


注意:
O(n2)的朴素算法是微不足道的。 你必须做得更好。


例:
给定nums = [-2,5,-1],下限= -2,上限= 2,
返回3。
三个范围是:[0,0],[2,2],[0,2]以及它们各自的和为:-2,-1,2。


解题思路:

递归思路,将 arr[] 均分为两半, 后一半使用sums[] 对应表示 从中间到对应下标的和,然后将sums排序,从 middle向低循环二叉检索

在sums中符合在lower和upper中的个数。


代码展示:

#include<iostream>#include<algorithm>#include<vector>#include <stdio.h>      /* printf */#include <stdlib.h>  using namespace std;//快排比较函数 int comp (const void * a, const void * b){  if(*(long*)a > *(long*)b ) return 1;   else if(*(long*)a < *(long*)b ) return-1;   else return 0;}class Solution {//从arr[]中二叉搜索找到比 target大的元素个数 int findBigger(long* arr,double target,int begin,int end) {if(arr[end] < target) return 0;if(arr[begin] > target) return end - begin+1;int l = begin ,r = end;while(l<r) {int middle = (l+r)/2;if(arr[middle] < target && arr[middle+1] > target) return end-middle;else if(arr[middle] > target) r = middle;else l = middle;}return 0;}//递归算法 int countSub(vector<int>& nums,int begin,int end,int lower,int upper) {//递归基 if(begin == end) return (nums[begin] >= lower&&nums[begin] <= upper)?1:0;if(begin > end) return 0;int middle = (begin+end)/2;long sumsSecond[end-middle] = {0};// sumsSecond[i] 表示 nums 从middle 到middle+i 的和 long sumTemp = 0;for(int i = middle+1 ;i <= end ;i++) {sumTemp+= nums[i];sumsSecond[i-middle-1] = sumTemp;} //将后一半的迭代和排序 qsort(sumsSecond,end-middle,sizeof(long),comp);int count = 0;sumTemp = 0;for(int i = middle;i>=begin;i--) {sumTemp+= nums[i];count += findBigger(sumsSecond,lower-sumTemp-0.5,0,end-middle-1) -findBigger(sumsSecond,upper-sumTemp+0.5,0,end-middle-1);}return countSub(nums,begin,middle,lower,upper)+ countSub(nums,middle+1,end,lower,upper) + count;}public:    int countRangeSum(vector<int>& nums, int lower, int upper) {        int len = nums.size();        if(len==0) return 0;        if(len == 1) return (nums[0] >= lower&&nums[0] <= upper)?1:0;return countSub(nums,0,len-1,lower,upper);     }   };int main() {Solution p;int a[] = {-2, 5, -1};vector<int> v(a,a+3);//cout << v.size()<<endl;int lower = -2, upper = 2;cout <<p.countRangeSum(v,lower,upper)<<endl;} 

题目状态:

0 0
原创粉丝点击