首页 > LintCode 249. 统计前面比自己小的数的个数

LintCode 249. 统计前面比自己小的数的个数

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

 注意事项

We suggest you finish problem Segment Tree Build, Segment Tree Query II and Count of Smaller Number first.

样例

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

解题思路:

  题目提示我们使用线段树,在这里我写了两种线段树的解法,一种TLE,一种正常通过;个人感觉两种写法需要因地制宜使用:

 

  思路1:每个线段树节点存储的是原始vector的index前后值以及该区间内的相应最大值,在查询时,通过区域以及最大值约束找到所有小于特定值的区间最后求和。

class SegmentTreeNode{	//线段树节点,其中max是当前区域内(left-right)最大值
public:int start,end,max;SegmentTreeNode2 * left;SegmentTreeNode2 * right;SegmentTreeNode2(int x,int y,int max){this->start = x;this->end = y;this->max = max;this->left = this->right = nullptr;}
};class Solution {
public:/*** @param A: an integer array* @return: A list of integers includes the index of the first number and the index of the last number*/vector countOfSmallerNumberII(vector &A) {// write your code hereauto tree = new SegmentTreeNode(0,A.size()-1,INT_MIN);buildTree(A,tree);vector ret;for(int i = 0;i &A,SegmentTreeNode * root){	//建立线段树,每个节点保存该区域内最大值int start = root->start;int end = root->end;if(start > end) return 0;if(start == end) {root->max = A[start];return A[start];}else{root->left = new SegmentTreeNode(start,(start+end)/2,INT_MIN);root->right = new SegmentTreeNode((start+end)/2+1,end,INT_MIN);int L_max = buildTree(A,root->left);int R_max = buildTree(A,root->right);root->max = L_max>R_max?L_max:R_max;return root->max;};}int query(SegmentTreeNode * root,int start,int end,int q){	//查询特定区域比q小的个数if(root == nullptr) return 0;if(root->start > end || root->end < start) return 0;if(root->start >= start && root->end <= end && root->maxend - root->start + 1;return query(root->left,start,end,q)+query(root->right,start,end,q);}
};

  这种解法TLE,时间复杂度在vector的size很大时很大,某种程度上来讲效率不及直接暴力法,但当所求数据较为集中时应该能提高一点速度。

 

思路2:对数据的区间建立线段树,在知道所有数据上界的情况下效率不错,能够正常通过

class SegmentTreeNode{//count表示当前区间所有的数个数
public:int start,end,count;SegmentTreeNode * left;SegmentTreeNode * right;SegmentTreeNode(int x,int y,int count){this->start = x;this->end = y;this->count = count;this->left = this->right = nullptr;}
};class Solution {
public:/*** @param A: an integer array* @return: A list of integers includes the index of the first number and the index of the last number*/vector countOfSmallerNumberII(vector &A) {// write your code herevector res;SegmentTreeNode * root = buildTree(0,10001);for(int i=0; i end) return nullptr;auto res = new SegmentTreeNode(start,end,0);if(start == end) return res;int mid = (start+end)/2;res->left = buildTree(start,mid);res->right = buildTree(mid+1,end);return res;}int query(SegmentTreeNode * root,int q){   //query函数用来查询当前区域内小于q的数的个数if(root == nullptr) return 0;if(q < root->start) return 0;if(q > root->end) return root->count;return query(root->left,q)+query(root->right,q);}void insert(SegmentTreeNode * root,int val){//将输入数据逐个插入,从上到下逐个更新countif(root == nullptr) return;if(root->start > val || root->end < val) return;if(root->start <= val && root->end >= val) ++root->count;insert(root->left,val);insert(root->right,val);}
}

  ps:这道题如果使用lintcode内置的SegmentTreeNode 数据结构中的count好像会出问题,最好定义自己的class

 

转载于:https://www.cnblogs.com/J1ac/p/8729389.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 对于范围的每个边界,您可以使用binary-search两次(使用bisect.bisect_left()).如果返回的索引相同,则没有交集(返回None).如果不是,则返回start_index处的元素(其中start_index是您的范围开始时获得的索引).这是代码:import bisectdef intersect_range...

  • service smartd start ...

  • http://www.cnblogs.com/little-ant/p/3196201.html simple_one_for_one vs one_for_one: 相同点: 这种Restart Strategy和one_for_one基本相同(即当一个child process挂掉后,仅仅重启该child process 而不影响...