zoukankan      html  css  js  c++  java
  • 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;
        }
    };
    
  • 相关阅读:
    视图中使用select a.* 更改了表a的结构 导致读取字段值时发生错位
    sql 压缩文件(rar或zip)
    单击触发jquery.autocomplete的两种方法
    CSS布局时容易出的小错误,导致浏览器不兼容或者各种不显示
    使用备份数据库.bal文件还原正在使用的数据库
    sql outer join
    利用GBK双字节编码突破PHP单引号转义限制进行SQL注入:set names gbk导致的sql注入
    对可操作对象的占用状态、锁定状态、解锁状态的一些方案
    回车转换成Tab
    DataGrid超级连接列
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/10306811.html
Copyright © 2011-2022 走看看