leetcode315. Count of Smaller Numbers After Self

题目leetcode315. Count of Smaller Numbers After Self
难度等级: hard

思路

首先最暴力的方法,就是二重循环遍历a[0 … (n - 1)]。对于每个a[i], 找到a[(i + 1) … (n - 1)]中比a[i]小的数的的个数。时间复杂度是n平方。优化的一个角度是,能不能地在a[(i + 1) … (n - 1)]中找到比a[i]小的数的的个数,于是想到BST,从后面遍历数组,然后插入BST中,对于每个数,先找到利用BST找到树中比该数小的数的个数,然后再将该数插入BST中。在构建BST时候,节点除了要记录节点数值外, 还要记录以该节点为根的树的节点个数,根据这个信息,可以使用分治策略很快找到比某个数小的数的个数。这里最关键的是如何使用分治找到SBT中比target小的数的个数, 如果根节点的数值 等于 target, 那么比target小的个数,就是根节点的左子树的节点个数, 如果target小于根节点数值, 那么到根节点的做子树中查找, 如果大于, 则等于根节点加上左子数节点个数在加上从右字数查找得到的个数

实现

struct Node {
    int data;
    int num;
    Node *left, *right;

    Node(int data) : data(data), num(1), left(NULL), right(NULL) {}
};

Node * insert(Node* root, int data) {
    if(root == NULL)
        return new Node(data);

    if(root->data > data)
        root->left = insert(root->left, data);
    else if (root->data < data)
        root->right = insert(root->right, data);

    root->num++;

    return root;
}


// the number of elements which < target
int search(Node * root, int target) {
    if (root == NULL) return 0;

    if (root->data >= target)
        return search(root->left, target);
    if(root->data < target){
        int tmp = root->num;
        if(root->right != NULL)
            tmp -= root->right->num;
        return tmp + search(root->right, target);
    }
}

class Solution {
public:
    vector<int> countSmaller(vector<int>& nums) {
        int size = nums.size();
        vector<int> vec(size);

        Node * root = NULL;
        for(int i = size - 1; i >= 0; i--) {
            vec[i] = search(root, nums[i]);
            root = insert(root, nums[i]);
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值