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

Posted INnoVation-V2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 315 计算右侧小于当前元素的个数相关的知识,希望对你有一定的参考价值。

方法一 二叉排序树

将传入数组从后往前依次插入二叉排序树中,每个节点由val(元素值) , count (元素出现次数) , left_count(比这个元素小的元素个数),插入完成后从前往后依次查询完成答案
以1 2 9 2 3 1 7为例
插入过程 若待插入值比当前节点值小,当前节点left_count+=1,转移至left_child,若为nullptr,则新建节点
     若待插入值比当前节点值大,那么转移到right_child,若为nullptr,则新建节点
     若待插入值和当前节点值相等,当前节点count+=1
查询过程 初始化 ans = 0
若待查询值比当前节点值小,那么移动至left_child,当前节点left_count - 1
若待查询值比当前节点值大,ans += node.count + node.left_count
若待查询值和当前节点值相等,ans += node.left_count ,当前节点count - 1

class Solution {
    struct Node {
        int val, count, left_count;
        Node *left, *right;

        Node() : val(-1), left(nullptr), right(nullptr), count(1), left_count(0) {}

        Node(int _val) : val(_val), left(nullptr), right(nullptr), count(1), left_count(0) {}
    };

public:
    void insert_to_tree(Node *&head, int val, bool equal) {
        Node *temp = head;
        while (true)
            if (val < temp->val) {
                ++temp->left_count;
                if (temp->left == nullptr) {
                    temp->left = new Node(val);
                    return;
                } else
                    temp = temp->left;
            } else if (val > temp->val) {
                if (temp->right == nullptr) {
                    temp->right = new Node(val);
                    return;
                } else
                    temp = temp->right;
            } else {
                ++temp->count;
                return;
            }
    }

    void update(vector<int>::iterator &x, int val, Node *head, unordered_map<int, int> &it) {
        int ans = 0;
        while (1) {
            if (val < head->val) {
                --head->left_count;
                head = head->left;
            } else if (val > head->val) {
                ans += head->count + head->left_count;
                head = head->right;
            } else {
                *x = ans + head->left_count;
                --head->count;
                return;
            }
        }
    }

    vector<int> countSmaller(vector<int> &nums) {
        if (nums.empty())
            return {};
        auto num = --nums.end();
        Node *head(new Node(*num));
        --num;
        for (int last = nums[0]; num != --nums.begin(); --num) {
            insert_to_tree(head, *num, last == *num);
            last = *num;
        }
        vector<int> ans(nums.size(), 0);
        auto _ans = ans.begin();
        unordered_map<int, int> it;
        for (const auto &x:nums) {
            update(_ans, x, head, it);
            ++_ans;
        }
        return ans;
    }
};

方法二 树状数组

class Solution {
    struct FenwickTree {
        FenwickTree(int _size) : result(_size + 1, 0) {}

        void update(int pos) {
            while (pos < result.size()) {
                ++result[pos];
                pos += lowbit(pos);
            }
        }

        int query(int pos) {
            int ans = 0;
            while (pos > 0) {
                ans += result[pos];
                pos -= lowbit(pos);
            }
            return ans;
        }

    private:
        vector<int> result;

        static inline int lowbit(int x) {
            return x & (-x);
        }
    };

public:
    vector<int> countSmaller(vector<int> &nums) {
        set<int> sorted(nums.begin(),nums.end());
        unordered_map<int, int> ranks;
        int rank = 0;
        for (const int num : sorted)
            ranks[num] = ++rank;

        FenwickTree save(ranks.size());
        vector<int> ans;
        for (int pos = nums.size() - 1; pos >= 0; --pos) {
            save.update(ranks[nums[pos]]);
            ans.push_back(save.query(ranks[nums[pos]] - 1));
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

以上是关于leetcode 315 计算右侧小于当前元素的个数的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

题目地址(315. 计算右侧小于当前元素的个数)

题目地址(315. 计算右侧小于当前元素的个数)