327. Count of Range Sum(Divide and Conquer)
阿新 • • 發佈:2019-02-17
題目:
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 = -2
, upper = 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; }
題目狀態: