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. SSTI注入绕过(沙盒逃逸原理一样)

    在python沙盒逃逸中绕过道理是一样的. 1.python沙盒中删除了很多模块,但是没有删除reload reload(__builtins__),重新加载被删除的模块,直接命令执行,只用于py2 ...

  2. 安装cloudbase-init和qga批处理

    @echo off title Auto Install color 1F ::CloudBase-Init echo. msiexec /i \\192.168.122.47\cloudbase\C ...

  3. SPOJ 364 Pocket Money 简单DP

    跟矩阵链乘同类型的题…… 输出用%llu不是%I64u…… 几组数据: 141+2*4+3*4+5*00*5*6+7*3+23+0+6+7+0+44*5+7*1*1+12*0+3*4*0+5*6+7+ ...

  4. 【现代程序设计】homework-01

    HOMEWORK-01 1) 建立 GitHub 账户, 把课上做的 “最大子数组之和” 程序签入 已完成. 2) 在 cnblogs.com 建立自己的博客. 写博客介绍自己的 GitHub 账户. ...

  5. 201621123034 《Java程序设计》第12周学习总结

    作业12-流与文件 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车 ...

  6. MVC4.0 bug 神奇的是事情 bool 值变成了 onclick ,非常奇怪的

    foreach (var item in ViewBag.PhotoGroupList) { // 这里很奇怪 item.IS_DISPLAY  是布尔值 如果直接写 @item.IS_DISPLAY ...

  7. 虚拟机——mnt_hgfs下无目录情况解决

    /mnt/hgfs下无目录情况解决: VMware8虚拟机安装Ubuntu 11.10使用share folders共享目录将虚拟机掉电关闭(不能暂停),设置share folders目录,重启虚拟机 ...

  8. Windows彻底删除不用的dc

    如果DC迁移,或者多台DC中的某台DC损坏,要退出历史舞台,一定要彻底的卸载,否则,系统会默认存在,一直同步,会出很多问题.怎么做才能彻底的从域中卸载呢?下面介绍一个个人认为很好用的方法:1.在存活的 ...

  9. mac使用基础

    Mac 系统的桌面 Mac 的桌面是一个很炫的3D, 背景是一张“星空”图. 2 Dock:  在桌面的下方有一排图标, 叫Dock, 用来快速启动程序, 进入文件夹, 它同时还可以停靠正在运行的程序 ...

  10. JS将JSON日期转换为指定格式的日期

    1.引入JS日期转换的函数库 function Format(now,mask) { var d = now; var zeroize = function (value, length) { if ...