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

Example:

Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:

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.

这道题给定了一个数组,让我们计算每个数字右边所有小于这个数字的个数,目测不能用 brute force,OJ 肯定不答应,那么为了提高运算效率,首先可以使用用二分搜索法,思路是将给定数组从最后一个开始,用二分法插入到一个新的数组,这样新数组就是有序的,那么此时该数字在新数组中的坐标就是原数组中其右边所有较小数字的个数,参见代码如下:

解法一:

// Binary Search
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int> t, res(nums.size());
for (int i = nums.size() - ; i >= ; --i) {
int left = , right = t.size();
while (left < right) {
int mid = left + (right - left) / ;
if (t[mid] >= nums[i]) right = mid;
else left = mid + ;
}
res[i] = right;
t.insert(t.begin() + right, nums[i]);
}
return res;
}
};

上面使用二分搜索法是一种插入排序的做法,我们还可以用 C++ 中的 STL 的一些自带的函数,比如求距离 distance,或是求第一个不小于当前数字的函数 lower_bound(),这里利用这两个函数代替了上一种方法中的二分搜索的部分,两种方法的核心思想都是相同的,构造有序数组,找出新加进来的数组在有序数组中对应的位置存入结果中即可,参见代码如下:

解法二:

// Insert Sort
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int> t, res(nums.size());
for (int i = nums.size() - ; i >= ; --i) {
int d = distance(t.begin(), lower_bound(t.begin(), t.end(), nums[i]));
res[i] = d;
t.insert(t.begin() + d, nums[i]);
}
return res;
}
};
再来看一种利用二分搜索树来解的方法,构造一棵二分搜索树,稍有不同的地方是需要加一个变量 smaller 来记录比当前结点值小的所有结点的个数,每插入一个结点,会判断其和根结点的大小,如果新的结点值小于根结点值,则其会插入到左子树中,此时要增加根结点的 smaller,并继续递归调用左子结点的 insert。如果结点值大于根结点值,则需要递归调用右子结点的 insert 并加上根结点的 smaller,并加1,参见代码如下:
解法三:
// Binary Search Tree
class Solution {
public:
struct Node {
int val, smaller;
Node *left, *right;
Node(int v, int s) : val(v), smaller(s), left(NULL), right(NULL) {}
};
int insert(Node*& root, int val) {
if (!root) return (root = new Node(val, )), ;
if (root->val > val) return root->smaller++, insert(root->left, val);
return insert(root->right, val) + root->smaller + (root->val < val ? : );
}
vector<int> countSmaller(vector<int>& nums) {
vector<int> res(nums.size());
Node *root = NULL;
for (int i = nums.size() - ; i >= ; --i) {
res[i] = insert(root, nums[i]);
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/315

类似题目:

Count of Range Sum

Queue Reconstruction by Height

Reverse Pairs

参考资料:

https://leetcode.com/problems/count-of-smaller-numbers-after-self/

https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76576/My-simple-AC-Java-Binary-Search-code

https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/138154/The-C%2B%2B-merge-sort-template-for-pairs-'i'-'j'-problem

https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76611/Short-Java-Binary-Index-Tree-BEAT-97.33-With-Detailed-Explanation

https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76657/3-ways-(Segment-Tree-Binary-Indexed-Tree-Binary-Search-Tree)-clean-python-code

https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76607/C%2B%2B-O(nlogn)-Time-O(n)-Space-MergeSort-Solution-with-Detail-Explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 315. Count of Smaller Numbers After Self 计算后面较小数字的个数的更多相关文章

  1. [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 ...

  2. 315 Count of Smaller Numbers After Self 计算右侧小于当前元素的个数

    给定一个整型数组 nums,按要求返回一个新的 counts 数组.数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于nums[i] 的元素的数量.例子:给定 nu ...

  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. leetcode 315. Count of Smaller Numbers After Self 两种思路(欢迎探讨更优解法)

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

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

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

  6. LeetCode 315. 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(HARD) 主席树

    Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的数. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树 ...

  8. 315.Count of Smaller Numbers After Self My Submissions Question

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

  9. 315. 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 ...

随机推荐

  1. CentOS7安装Oracle 11g数据库

    转载:https://blog.csdn.net/lia17/article/details/82256565 rpm -ivh --force --nodeps *.rpm 强制装 rpm依赖包下载 ...

  2. 移动端rem布局,用户调整手机字体大小或浏览器字体大小后导致页面布局出错问题

    一.用户修改手机字体设置大小,影响App里打开的web页面. 手机字体设置大小,影响App的页面.Android的可以通过webview配置webview.getSettings().setTextZ ...

  3. NPOI 帮助类

    NPOI 帮助类 代码实现了来自于互联网 using System; using System.Data; using System.IO; using System.Text; using NPOI ...

  4. Visual Studio 定制模板类---详细步骤

    1.先定义一个类文件,将要定义的信息写入类文件 比如我每次写一个命令都是这个套路,要继承接口,要写上相应的特性,每次都 是重复的工作: 2.提取类模板 项目=>导出模板 这里你可以导出项目模板和 ...

  5. 【机器学习笔记】来吧!解析k-NN

    序: 监督型学习与无监督学习,其最主要区别在于:已知的数据里面有没有标签(作为区别数据的内容). 监督学习大概是这个套路: 1.给定很多很多数据(假设2000个图片),并且给每个数据加上标签(与图片一 ...

  6. ORACLE 求和(多列)

    SELECT SUM(列名),SUM(列名),SUM(列名),SUM(列名) FROM 表名

  7. sess文件编译输出css的四种方式以及使用

    sess文件输出css有下面四种方式: :nested(嵌套) :compact(紧凑) :expanded(展开) :compressed(压缩) 如何使用: sass --watch style. ...

  8. SAP MM 公司间STO里外向交货单与内向交货单里序列号对应关系

    SAP MM 公司间STO里外向交货单与内向交货单里序列号对应关系 笔者所在的A项目,后勤模块里有启用HU管理,序列号管理,批次管理等功能,以实现各个业务场景下的追溯. 公司间转储订单流程里,如果是整 ...

  9. 电信NBIOT 5 - NB73模块下行测试(自己平台-电线平台-NB73)

    电信NBIOT 1 - 数据上行(中国电信开发者平台对接流程) 电信NBIOT 2 - 数据上行(中间件获取电信消息通知) 电信NBIOT 3 - 数据下行 电信NBIOT 4 - NB73模块上行测 ...

  10. 【vuejs】vue数组操作

    问题:两种操作都能给数组添加数据,但是利用下标添加数据不会自动在视图中渲染,这个是和vue自己的规定有关,这里记录一下 网上到原因,这里附转载链接 点我传送 官网相关说明传送门