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. python的inspect模块

    一.type and members 1. inspect.getmembers(object[, predicate]) 第二个参数通常可以根据需要调用如下16个方法: 返回值为object的所有成 ...

  2. 常用模块(time)

    import time # data = time.time() # 获取时间戳# data = time.localtime() # 获取操作系统时间,也称本地时间,可传入时间戳# data = t ...

  3. python 学习分享-paramiko模块

    paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Solaris, BS ...

  4. ssh.sh_for_centos

    #!/bin/bash sed -i 's/#PermitRootLogin yes/PermitRootLogin yes/g' /etc/ssh/sshd_config sed -i 's/#Us ...

  5. CentOS7 编译安装nodejs,配置环境变量记录

    每次都装,每次都查 阿里云备案了一个域名,续费了好多年,但是没钱买服务器,就挂在github上.今天收到消息:域名解析服务器不在阿里云,要被GG.只能咬牙买了个阿里云乞丐版. 所有服务都装好了,pin ...

  6. Elasticsearch查询优化总结

    查询优化 1 从提高查询精确度进行优化: 本部分主要针对全文搜索进行探究. 1.1 倒排索引 1.1.1 什么是倒排索引: 一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文 ...

  7. 8.2 前端检索的敏感词过滤的Python实现(针对元搜索)

    对于前端的搜索内容进行控制,比如敏感词过滤,同样使用socket,这里使用Python语言做一个demo.这里不得不感叹一句,socket真是太神奇了,可以跨语言把功能封装,为前端提供服务. 下面就是 ...

  8. 如何修改win10管理员账户

    首先按下win+x组合键,如下图所示   在弹出菜单选择运行,如下图所示   在运行框中输入netplwiz后点击确定按钮   将下图中要使用本计算机必须输入用户名和密码前面的勾去掉,点击下方应用按钮 ...

  9. Asp .Net MVC中常用过滤属性类

    /// <summary> /// /// </summary> public class AjaxOnlyAttribute : ActionFilterAttribute ...

  10. 【IDEA】IDEA中部署的项目添加Tomcat自带的一些项目

    在IDEA部署项目的时候发现没有tomcat自带的一些项目,有时候我们需要tomcat自带的项目查看一些配置的信息,经过查阅资料后做记录如下: 1.在Eclipse中点击Run ->Edit C ...