315. 计算右侧小于当前元素的个数

给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。

示例:

输入: [5,2,6,1]
输出: [2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.

思路:

从最右边开始逐步构建一颗二叉搜索树

树中维护有节点的值,小于该节点的数的数量less,左右节点,相同数字的数量

在每个位置构建完成树之后,立即计算该位置小于该数的个数,由于新的点加入之后一定是处于叶节点的。

所以从根节点开始:

1.如果节点值大于目标值,那么递归到节点的左节点进行计数

2.如果节点值等于目标值,返回该节点处less的值

3.节点值小于目标值,返回节点自身数量+less+递归右节点(因为大于节点值也有可能小于目标值)

Code:

class Solution {
public:
    struct node{
        int small;
        int val;
        int self=1;
        node * left=NULL;
        node * right=NULL;
        node(int val,int small):small(small),val(val){};
    };
    node* add(node* root,int val)
    {
        if(root==NULL)return new node(val,0);
        if(val==root->val) root->self+=1;
       else if(val>root->val) root->right=add(root->right,val);
        else {root->left=add(root->left,val);root->small+=1;}
        return root;
    }
    int getnum(node* root,int val)
    {
        if(root==NULL)return 0;
        if(root->val==val)return root->small;
        if(root->val<val) return root->small+root->self+getnum(root->right,val);
        if(root->val>val) return getnum(root->left,val);
        
    }
    vector<int> countSmaller(vector<int>& nums) {
        int n=nums.size();
        if(n==0)return {};
        if(n==1) return {0};
        
        vector<int>count(n,0);       
        node*root=new node(nums[n-1],0);
        for(int i=n-2;i>=0;i--)
        {
            root=add(root,nums[i]);
            count[i]=getnum(root,nums[i]);
        }
        return count;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值