You are given an integer array nums and you have to return a new counts array.The counts array has the property where counts[i]
is the number of smaller elements to the right of nums[i]
.
Example:
Given nums = [5, 2, 6, 1] To the right of 5 there are 2 smaller elements (2 and 1). To the right of 2 there is only 1 smaller element (1). To the right of 6 there is 1 smaller element (1). To the right of 1 there is 0 smaller element.
Return the array [2, 1, 1, 0]
.
题目给定一个数组nums,要求求得每一个数的右边比它小的数的个数。我想到的是用二叉搜索树来做。建立一棵树,往里面插值(从nums的尾到头),比当前节点的val值大的往右走,否则往左走,直到到达一个空节点,则设该节点的val值为该值。在插入的过程中,每个节点用count值来记录左子树节点的总数(插入一个值时往左走则当前节点count值加一),然后如果值往右走,说明该值大于该节点的val值和该节点左子树所有节点的val值,于是结果要加上当前节点的count值加一。这样在插入所有值的同时结果也算好了。
代码:
class Solution {
public:
struct BST
{
int val;
int count;
BST *left,*right;
BST(int v,int c=0,BST *l=NULL,BST *r=NULL):
val(v),count(c),left(l),right(r){}
};
void insert(BST *&root,int num,int &ret)
{
if(root==NULL)
{
root=new BST(num);
return;
}
if(num>root->val)
{
ret+=root->count+1;
insert(root->right,num,ret);
}
else
{
root->count++;
insert(root->left,num,ret);
}
}
vector<int> countSmaller(vector<int>& nums)
{
vector<int>res;
if(nums.empty()) return res;
int n=nums.size();
res.resize(n,0);
BST *root=new BST(nums[n-1]);
for(int i=n-2;i>=0;i--)
{
insert(root,nums[i],res[i]);
}
return res;
}
};