Arithmetic problem | 统计前面比自己小的数的个数

来源:互联网 发布:日本南北朝 知乎 编辑:程序博客网 时间:2024/06/06 04:17

题目如下:

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


样例

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


解题时产生3个思路:

1:暴力向ai前面的元素比较扫描,复杂度最高。

2:这题目要的是前面比自己小的数的个数,那么,把它放在已排序的特化环境里显然会变得更加简单,排序后找到比ai大的元素即可解题。

3:由思路2衍生而来,通过缓存某区间点的“比其小的数个数”,从而舍去半部分已知小的数。这里使用类似二叉查找树的结构,遇大放右,遇小放左。那么ai元素在树中经历结点的所有“左节点”个数即为解。这样不但可以舍去半部分已知小的数,对重复元素的处理也会变得相对简单。


结构定义如下:

typedef struct CNODE{int l_count = 0, data =0, rep = 0;CNODE *left_node=nullptr,*right_node=nullptr;CNODE(int num) { data = num; }~CNODE() { if (left_node)delete left_node; if (right_node) delete right_node; }}CNODE;

思路三代码实现如下:

int* Method(vector<int> &source){int count; int *res = new int[source.size()];CNODE *temp = nullptr; res[0] = 0;CNODE *root = new CNODE(source[0]);for (int i = 1; i < (int)source.size(); ++i) {temp = root; count = 0;while (true) {if (temp->data > source[i]) {temp->l_count++;if (temp->left_node)temp = temp->left_node;else {temp->left_node = new CNODE(source[i]); break;}}else if (temp->data < source[i]) {count += temp->l_count + temp->rep + 1;if (temp->right_node)temp = temp->right_node;else {temp->right_node = new CNODE(source[i]); break;}}else {count += temp->l_count, temp->rep++; break;}}res[i] = count;}delete root;return res;}


12 0
原创粉丝点击