统计前面比自己小的数的个数

来源:互联网 发布:python 驼峰转 编辑:程序博客网 时间:2024/05/17 23:47

给定一个整数数组(下标由 0 到 n-1, n 表示数组的规模,取值范围由 0 到10000)。对于数组中的每个 ai 元素,请计算 ai 前的数中比它小的元素的数量。

样例

对于数组[1,2,7,8,5] ,返回 [0,1,2,3,2]

说明

在做此题前,最好先完成以下三道题: 线段树的构造, 线段树的查询 II,和 比给定数小的项目数 I 。

class Node{public:    Node(int _start, int _end) :        start(_start), end(_end), left(nullptr), right(nullptr),        cnt(0) {}        int start, end;    Node *left, *right;    int cnt;};    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        Node *root = build(0, 20000);        vector<int> res;                for (int i = 0; i < A.size(); i++)        {            int cnt = query(root, 0, A[i] - 1);            res.push_back(cnt);            modify(root, A[i]);        }                return res;    }private:    Node *build(int start, int end)    {        if (start > end)        {            return NULL;        }        if (start == end)        {            return new Node(start, end);        }                int mid = start + ((end - start) >> 1);                Node *root = new Node(start, end);        root->left = build(start, mid);        root->right = build(mid + 1, end);                return root;    }        void modify(Node *root, int idx){        if (root == NULL)         {            return;        }                if (root->start == root->end && root->start == idx)        {            ++(root->cnt);            return;        }                int mid = root->start + ((root->end - root->start) >> 1);        if (mid >= idx)        {            modify(root->left, idx);        }        else        {            modify(root->right, idx);        }                root->cnt = root->left->cnt + (root->right ? root->right->cnt : 0);    }        int query(Node *root, int start, int end)    {        if (root->end < start || root->start > end)        {            return 0;        }        if (root->start >= start && root->end <= end)        {            return root->cnt;        }                    int mid = root->start + ((root->end - root->start) >> 1);        if (mid >= end)         {            return query(root->left, start, end);        }        if (mid < start)         {            return query(root->right, start, end);        }                int leftRes = query(root->left, start, mid);        int rightRes = query(root->right, mid + 1, end);                return leftRes + rightRes;    }};


0 0