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. 参加2018之江杯全球人工智能大赛
:视频识别&问答

    学习了一段时间的AI,用天池大赛来检验一下自己的学习成果. 题目:参赛者需对给定的短视频进行内容识别和分析,并回答每一个视频对应的问题.细节请到阿里天池搜索. 两种思路 1 将视频截成一帧一帧的图片, ...

  2. python爬取动态网页2,从JavaScript文件读取内容

    import requests import json head = {"user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) ...

  3. [bzoj3456] 城市规划 [递推+多项式求逆]

    题面 bzoj权限题面 离线题面 思路 orz Miskcoo ! 先考虑怎么算这个图的数量 设$f(i)$表示$i$个点的联通有标号无向图个数,$g(i)$表示$n$个点的有标号无向图个数(可以不连 ...

  4. 小L的占卜

    小L的占卜 题目描述 小 X 的妹妹小 L 是一名 XXX 国的占卜师,她平日的工作就是为 X 国进行占卜. X 国的占卜殿中有一条长度为 NNN 米的走廊,先人在走廊的每一米都放置了一座神龛,第 i ...

  5. placeholer改变默认灰色

    input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{ color:#7b642c; } input:-moz-pl ...

  6. 无法安装MVC3,一直卡在vs10-kb2483190

    原文发布时间为:2011-05-15 -- 来源于本人的百度文章 [由搬家工具导入] 无法安装MVC3,一直卡在vs10-kb2483190 解决方案: 1、用winrar 解压 MVC3安装文件 2 ...

  7. poj 2187 Beauty Contest(二维凸包旋转卡壳)

    D - Beauty Contest Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  8. 厌倦了ListBox打印消息,使用RichTextBox试试吧

    背景 Winform打印后台线程运行时消息,习惯用ListBox,有时候某行消息过长,设置个Tooltip控件提示全部信息.后来无意中看到同事使用RichTextBox打印消息,然后在不同的消息类别上 ...

  9. C#的泛型委托Predicate/Func/Action

    Predicate<T> 是一个委托,它代表了一个方法,它的定义是: namespace System {    // 摘要:    表示定义一组条件并确定指定对象是否符合这些条件的方法. ...

  10. GHC extensions

    OverloadedStrings 这是最常见的一个扩展,很多时候都能看到   Haskell中,数字是num的多态,比如:   a :: Int a = 1   b :: Double b = 1 ...