LintCode统计前面比自己小的数的个数(线段树)

用到了线段树,这种数据结构在数值范围不大的情况下可以很方便地达到o(logn)的查找效率。

做过 线段树的构造, 线段树的查询 II后再做就不难了。

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

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

struct Node{//线段树节点
    int begin;
    int end;
    int mid;
    int count;
    Node* left;
    Node* right;
    
    Node(int begin, int end){
        this->begin = begin;
        this->end = end;
        this->mid = (begin + end) / 2;
        this->count = 0;
        this->left = NULL;
        this->right = NULL;
    }
    
    int add(int num){ //返回线段树中比num大的值的数量
        ++count;
        if(begin == end){
            return 0;
        }else{
            if(left == NULL){
                left = new Node(begin, mid);
            }
            if(right == NULL){
                right = new Node(mid + 1, end);
            }
            
            if(num <= mid){
                return left->add(num);
            }else{
                return left->count + right->add(num);
            }
        }
    }
    
    ~Node(){
        delete this->left;
        delete this->right;
    }
};

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
        vector<int> r;
        if(A.size() == 0){
            return r;
        }
        
        int min = A[0];
        int max = A[0];
        for(int i = 0; i < A.size(); ++i){//找出最大和最小值
            if(A[i] < min){
                min = A[i];
            }
            
            if(A[i] > max){
                max = A[i];
            }
        }
        
        Node* node = new Node(min, max); //一边构建线段树一边计算答案
        for(int i = 0; i < A.size(); ++i){
            r.push_back(node->add(A[i]));
        }
        delete node;
        return r;
    }
};


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值