You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Given nums = [5, 2, 6, 1]

To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

Return the array [2, 1, 1, 0].

思路:O(nlogn)复杂度算法。

将数组排序然后构建二叉搜索树。一开始二叉搜索树上的节点都标记为未处理过。然后我们从所给的nums数组的最后一个数倒着向前遍历,依次将每一个数在二叉搜索树中对应的节点标记为处理过,然后返回二叉搜索树中已经被标记为处理过,且小于该值的个数。

具体实现中,我们在每一个节点中设置一个count变量,计数以该节点为根节点的子树中已经被标记为处理过的节点个数,初始为0。之后算法运行过程中不断更新该值并通过该值更快地求解。本质上来说这是一个线段树的应用。

当我们要求二叉搜索树中有多少被处理过的节点值小于所给的值时,有三种情况:

  • 所给的值是当前子树的根节点。则小于它的数只可能在左子树中,因此返回根节点左孩子的count值。
  • 所给的值在当前子树的左子树中。则小于它的数只可能在左子树中,因此递归求解,返回左子树中被处理过且小于所给值的节点个数。
  • 所给的值在当前子树的右子树中。则小于它的数可能在左子树中或者是该根节点,或者在右子树中。因此递归求解,返回左子树和根节点中被处理过且小于所给值的节点个数加上右子树中被处理过且小于所给值的节点个数。

二叉搜索树的构建O(n),二叉搜索树的单次查找更新操作O(logn)。 总复杂度为O(n) + O(nlogn) = O(nlogn)

 class treeNode {
public:
int val, count;
treeNode *left, *right;
treeNode(int v) : val(v), count(), left(NULL), right(NULL) {}
};
class Solution {
public:
//convert a sortedArray to a binary search tree and return a pointer to its root node
treeNode* buildTree(vector<int>& sortedArray, int left, int right) {
if (right < left) return NULL;
int mid = left + (right - left) / ;
treeNode* cur = new treeNode(sortedArray[mid]);
cur->left = buildTree(sortedArray, left, mid - );
cur->right = buildTree(sortedArray, mid + , right);
return cur;
}
//count numbers in this binary search tree that were processed and are less than the target
int update(treeNode* node, int target) {
if (node == NULL) return -;
if (node->val == target) {
node->count++;
return node->left ? node->left->count : ;
}
else if (node->val < target) {
int lessCount = node->count - node->right->count;
int rightCount = update(node->right, target);
node->count++;
return lessCount + rightCount;
}
else {
int leftCount = update(node->left, target);
node->count++;
return leftCount;
}
}
vector<int> countSmaller(vector<int>& nums) {
vector<int> sortedArray = nums;
sort(sortedArray.begin(), sortedArray.end(), less<int>());
treeNode* node = buildTree(sortedArray, , sortedArray.size() - );
vector<int> res(nums.size());
for (int i = nums.size() - ; i >= ; i--)
res[i] = update(node, nums[i]);
return res;
}
};

Count of Smaller Numbers After Self -- LeetCode的更多相关文章

  1. leetcode 315. Count of Smaller Numbers After Self 两种思路(欢迎探讨更优解法)

    说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...

  2. leetcode 315. Count of Smaller Numbers After Self 两种思路

    说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...

  3. [LeetCode] 315. Count of Smaller Numbers After Self (Hard)

    315. Count of Smaller Numbers After Self class Solution { public: vector<int> countSmaller(vec ...

  4. [Swift]LeetCode315. 计算右侧小于当前元素的个数 | Count of Smaller Numbers After Self

    You are given an integer array nums and you have to return a new countsarray. The counts array has t ...

  5. [LeetCode] Count of Smaller Numbers After Self 计算后面较小数字的个数

    You are given an integer array nums and you have to return a new counts array. The counts array has ...

  6. LeetCode Count of Smaller Numbers After Self

    原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...

  7. LeetCode 315. Count of Smaller Numbers After Self

    原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...

  8. [LeetCode] 315. Count of Smaller Numbers After Self 计算后面较小数字的个数

    You are given an integer array nums and you have to return a new counts array. The countsarray has t ...

  9. leetcode@ [315/215] Count of Smaller Numbers After Self / Kth Largest Element in an Array (BST)

    https://leetcode.com/problems/count-of-smaller-numbers-after-self/ You are given an integer array nu ...

随机推荐

  1. sentry

    https://docs.sentry.io/quickstart/?platform=javascript

  2. C#泛型和泛型约束

    一.泛型: 所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型.泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用. 二.泛型约束: 转自:http://ww ...

  3. RAID介绍和实现

    RAID的全称是廉价磁盘冗余阵列(Redundant Array of Inexpensive Disks),于1987年由美国Berkeley 大学的两名工程师提出的. RAID出现的,最初目的是将 ...

  4. 【志银】php5.6-Apache2.4-mysql5.6环境配置(win7_64位)

    ----------------------------------------------------- ★软件工具:(下载时注意下载相应版本,不同版本安装细节可能会有差异!!) 1>http ...

  5. 动态删边SPFA: [HNOI2014]道路堵塞

    [HNOI2014]道路堵塞 题目描述 $A$ 国有 $N$座城市,依次标为$1$到$N$.同时,在这$N$座城市间有$M$条单向道路,每条道路的长度是一个正整数.现在,$A$国交通部指定了一条从城市 ...

  6. rownum浅谈(二)

    上篇说到rownum和order by及索引列的关系,明白了通过构建一个子查询把查询结果固定住再取数就可以了 .还是取最近10条创建的用户: select * from (select u.* fro ...

  7. VC调试篇:减少运行时错误,中断所有异常

    问题简述 我在Win7下写的MFC程序,想让它在winXP下运行.一般情况下,如果所有的依赖库都可以在XP下运行的话,那么在XP下运行时没问题的.但是,结果却... 本来程序在win7下运行得好好的, ...

  8. YouTube高效传输策略:节省14%带宽 用户体验提升

    视频平台会侦测用户端的带宽来调整码率及分辨率,但通常只考虑到编码器的比特率率--质量关联,忽略了用户的可用带宽影响.YouTube团队通过让视频流匹配用户带宽,不仅节省了带宽,还有效提升了用户主观体验 ...

  9. 命令__cp、scp(Secure Copy)

    cp命令:区别:硬链接原文件&链接文件公用一个inode号,说明他们是同一个文件,而软链接原文件&链接文件拥有不同的inode号,表明他们是两个不同的文件: 在文件属性上软链接明确写出 ...

  10. java自定义类型 比较排序 Comparator接口

    String service_time = "6:00:00,7:00:00,8:00:00,9:00:00,10:00:00,11:00:00,12:00:00,13:00:00,14:0 ...