用到了线段树,这种数据结构在数值范围不大的情况下可以很方便地达到o(logn)的查找效率。
给定一个整数数组(下标由 0 到 n-1, n 表示数组的规模,取值范围由 0 到10000)。对于数组中的每个 ai
元素,请计算 ai
前的数中比它小的元素的数量。
样例:对于数组[1,2,7,8,5]
,返回 [0,1,2,3,2]
struct Node{//线段树节点
int begin;
int end;
int mid;
int count;
Node* left;
Node* right;
Node(int begin, int end){
this->begin = begin;
this->end = end;
this->mid = (begin + end) / 2;
this->count = 0;
this->left = NULL;
this->right = NULL;
}
int add(int num){ //返回线段树中比num大的值的数量
++count;
if(begin == end){
return 0;
}else{
if(left == NULL){
left = new Node(begin, mid);
}
if(right == NULL){
right = new Node(mid + 1, end);
}
if(num <= mid){
return left->add(num);
}else{
return left->count + right->add(num);
}
}
}
~Node(){
delete this->left;
delete this->right;
}
};
class Solution {
public:
/**
* @param A: An integer array
* @return: Count the number of element before this element 'ai' is
* smaller than it and return count number array
*/
vector<int> countOfSmallerNumberII(vector<int> &A) {
// write your code here
vector<int> r;
if(A.size() == 0){
return r;
}
int min = A[0];
int max = A[0];
for(int i = 0; i < A.size(); ++i){//找出最大和最小值
if(A[i] < min){
min = A[i];
}
if(A[i] > max){
max = A[i];
}
}
Node* node = new Node(min, max); //一边构建线段树一边计算答案
for(int i = 0; i < A.size(); ++i){
r.push_back(node->add(A[i]));
}
delete node;
return r;
}
};